Entity Framework Validation with IValidatableObject Example

With Entity Framework, data annotations are a great way to validate entity data from a single property. But what if we want to check entity data against two or more properties? For more complex validation strategies we can implement IValidatableObject in our poco classes.

In this example we have a simple User poco with a Name and Nick property. We need to ensure that Name and Nick are not equal and Nick starts with an @ sign. To do this we implement the Data Annotations IValidatableObject interface which requires a Validate method. Validate returns a collection of ValidationResult.

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
 
namespace CodeFirstMail.Pocos
{
    public class User : IEntity, IValidatableObject
    {
        public string Name { get; set; }
        public string Nick { get; set; }
        public string Address { get; set; }
        public int Id { get; set; }
 
        #region IValidatableObject Members
 
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (Name == Nick)
            {
                yield return new ValidationResult(
                    "Name and Nick must be different.",
                    new[] {"Name", "Nick"});
            }
 
            if (!Nick.StartsWith("@"))
            {
                yield return new ValidationResult(
                    "Nick must start with @.",
                    new[] {"Nick"});
            }
        }
 
        #endregion
    }
}

Let’s use the test from our former example on data annotations to check for these validation errors explicitly. Once we make a call to our DbContext SaveChanges method, the Validate method of each added or modified entity will be called automatically.

using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Diagnostics;
using CodeFirstMail.Context;
using CodeFirstMail.Pocos;
using Microsoft.VisualStudio.TestTools.UnitTesting;
 
namespace CodeFirstTests
{
    [TestClass]
    public class MailContextTest
    {
        [TestMethod]
        [ExpectedException(typeof (DbEntityValidationException))]
        public void EntityValidationShouldThrowDbEntityValidationException()
        {
            Database.SetInitializer(
                new DropCreateDatabaseIfModelChanges<MailContext>());
 
            using (var mailContext = new MailContext())
            {
                try
                {
                    var user =
                        new User
                            {
                                Name = "Leon",  // The Name is fine, 
                                Nick = "Leon",  // but Nick is the same.
                            };
 
                    mailContext.Users.Add(user);
                    mailContext.SaveChanges();
                }
                catch (DbEntityValidationException ex)
                {
                    LogValidationErrors(ex);
                    throw;
                }
            }
        }
 
        private static void LogValidationErrors(DbEntityValidationException ex)
        {
            foreach (DbEntityValidationResult validation 
                in ex.EntityValidationErrors)
            {
                Debug.WriteLine(
                    "Error in entity {0}",
                    validation.Entry.Entity);
 
                foreach (DbValidationError propertyError 
                    in validation.ValidationErrors)
                {
                    Debug.WriteLine(
                        "Error in property {0}: {1}",
                        propertyError.PropertyName,
                        propertyError.ErrorMessage);
                }
            }
        }
    }
}

And here are the test results… Note the validation errors for Name as well as Nick for uniqueness.

Entity Framework IValidatableObject Test

WCF Global Exception Handling Attribute and IErrorHandler

Exception handling in WCF can clutter your code with the same error handling routine over and over again. This is especially true when you want to provide some meaningful, yet safe, FaultExceptions back to the client. Wouldn’t it be nice if we had a way to handle these kind of exceptions on a more global service scope?

In this example we have a basic WCF service called SomeService with one operation called SomeFailingOperation. We need to handle exceptions from all service operations by logging what went wrong. We also need to return a generic vague FaultException back to the client stating what operation failed.

To do this we need to create an ErrorHandler first by implementing the IErrorHandler interface found in the System.ServiceModel.Dispatcher namespace. The HandleError method enables error handling and returns true to abort the current session. The ProvideFault method is the place where we provide our custom FaultException for our client. This is also the spot to do some kind of error logging.

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
 
namespace WcfService
{
    public class GlobalExceptionHandler : IErrorHandler
    {
        #region IErrorHandler Members
 
        public bool HandleError(Exception ex)
        {
            return true;
        }
 
        public void ProvideFault(Exception ex, MessageVersion version,
                                 ref Message msg)
        {
            // Do some logging here
 
            var newEx = new FaultException(
                string.Format("CALLED FROM YOUR GLOBAL EXCEPTION HANDLER BY {0}",
                              ex.TargetSite.Name));
 
            MessageFault msgFault = newEx.CreateMessageFault();
            msg = Message.CreateMessage(version, msgFault, newEx.Action);
        }
 
        #endregion
    }
}

Now we need to create a custom Service Behaviour Attribute to let WCF know that we want to use this global error handler whenever an exception occurs. We do this by deriving a class derived from Attribute and also implement the IServiceBehavior interface. In the constructor of this service behavior class we get the error handler type, like the one we showed here.

We only need to create this error handler once ApplyDispatchBehavior is called. In this method we can ‘inject’ our error handler. We do this by instantiating the handler with a call to Activator.CreateInstance and then add the newly created error handler to each channel dispatchers errorhandlers collection.

using System;
using System.Collections.ObjectModel;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
 
namespace WcfService
{
    public class GlobalExceptionHandlerBehaviourAttribute : Attribute, IServiceBehavior
    {
        private readonly Type _errorHandlerType;
 
        public GlobalExceptionHandlerBehaviourAttribute(Type errorHandlerType)
        {
            _errorHandlerType = errorHandlerType;
        }
 
        #region IServiceBehavior Members
 
        public void Validate(ServiceDescription description,
                             ServiceHostBase serviceHostBase)
        {
        }
 
        public void AddBindingParameters(ServiceDescription description,
                                         ServiceHostBase serviceHostBase,
                                         Collection<ServiceEndpoint> endpoints,
                                         BindingParameterCollection parameters)
        {
        }
 
        public void ApplyDispatchBehavior(ServiceDescription description,
                                          ServiceHostBase serviceHostBase)
        {
            var handler =
                (IErrorHandler) Activator.CreateInstance(_errorHandlerType);
 
            foreach (ChannelDispatcherBase dispatcherBase in 
                serviceHostBase.ChannelDispatchers)
            {
                var channelDispatcher = dispatcherBase as ChannelDispatcher;
                if (channelDispatcher != null)
                    channelDispatcher.ErrorHandlers.Add(handler);
            }
        }
 
        #endregion
    }
}

Finally, all we need to do is to decorate our Service class with our GlobalExceptionHandlerBehaviour attribute providing the type of our custom error handler and we are done.

using System;
 
namespace WcfService
{
    [GlobalExceptionHandlerBehaviour(typeof (GlobalExceptionHandler))]
    public class SomeService : ISomeService
    {
        #region ISomeService Members
 
        public string SomeFailingOperation()
        {
            throw new Exception("Kaboom");
            return null;
        }
 
        #endregion
    }
}

For each operation in our WCF service, whenever an exception is thrown, our global error handlers ProvideFault method is called and a custom FaultException is sent back to the client. So if we make a call to SomeFailingOperation…

WCF Global Exception Handling Error Handler Message

Simple Entity Framework Data Validation Example

In a previous example we explored validation options using Data Annotations. We decorate our domain class properties with some basic validation rules like Required, MaxLength, Range and so on. When we make a call to the DbContext SaveChanges method, these validation rules are applied to the properties about to be saved, preventing faulty data to get to our database.

In this example we take a first look at what validation exception Entity Framework throws and how to retrieve the property specific information on these errors. We have a basic EmailUser poco class with an Id, Name and Address property. The Name property is required and must be at least five characters long. The Address property is also required and must be a valid email address verified by using a regular expression pattern.

using System.ComponentModel.DataAnnotations;
 
namespace CodeFirstMail.Pocos
{
    public class EmailUser : IEntity
    {
        private const string RegExEmailPattern =
            @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$";
 
        public int Id { get; set; }
 
        [Required, MinLength(5)]
        public string Name { get; set; }
 
        [Required, RegularExpression(RegExEmailPattern)]
        public string Address { get; set; }
    }
}

We write a test to see what happens when the validation requirements aren’t met. We make some obvious mistakes in the EmailUser object for both Name and Address.

using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Diagnostics;
using CodeFirstMail.Context;
using CodeFirstMail.Pocos;
using Microsoft.VisualStudio.TestTools.UnitTesting;
 
namespace CodeFirstTests
{
    [TestClass]
    public class MailContextTest
    {
        [TestMethod]
        [ExpectedException(typeof (DbEntityValidationException))]
        public void EntityValidationShouldThrowDbEntityValidationException()
        {
            Database.SetInitializer(
                new DropCreateDatabaseIfModelChanges<MailContext>());
 
            using (var mailContext = new MailContext())
            {
                try
                {
                    var userManon =
                        new EmailUser
                            {
                                Name = "Mnon",                  // too short
                                Address = "manon@bussel..net"   // double dot
                            };
 
                    mailContext.EmailUsers.Add(userManon);
                    mailContext.SaveChanges();
                }
                catch (DbEntityValidationException ex)
                {
                    LogValidationErrors(ex);
                    throw;
                }
            }
        }

We expect (and in fact wrongly assume) an exception of type DbEntityValidationException to be thrown. In the LogValidationErrors method we write all validation errors to the Debug output.

        private static void LogValidationErrors(DbEntityValidationException ex)
        {
            foreach (DbEntityValidationResult validation 
                in ex.EntityValidationErrors)
            {
                Debug.WriteLine(
                    "Error in entity {0}",
                    validation.Entry.Entity);
 
                foreach (DbValidationError propertyError 
                    in validation.ValidationErrors)
                {
                    Debug.WriteLine(
                        "Error in property {0}: {1}",
                        propertyError.PropertyName,
                        propertyError.ErrorMessage);
                }
            }
        }
    }
}

We run our test and indeed get the two validation errors for the Name and Address properties with some default error description. Not very useful to present to our users of course, but very handy while developing.

  • Error in entity CodeFirstMail.Pocos.EmailUser
  • Error in property Name: The field Name must be a string or array type with a minimum length of ’5′.
  • Error in property Address: The field Address must match the regular expression ‘^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$’.

Entity Framework Data Validation Test

That’s basically it. In upcoming examples we explore more advanced issues of Entity Framework Data Validation.

Mindstorms Nxt Robot Performing QuickSort Algorithm

It’s robot time once again. After creating Ms. ColorSortress I decided it was time to create a .Net driven Lego bot. This cheesy robot, called SortAlgoBot, performs a classic Quicksort sorting algorithm on an array of twelve fresh colored Lego balls. It detects all colors in the first roundtrip. Then the actual sorting starts and all ‘swaps’ the algorithm makes are executed by the bot.

Build with a single Lego Mindstorms NXT 2.0 kit and some extra Lego Technic parts, like the Linear Actuator for some ball dropping. Programmed in C# with VisualStudio 2010 and the excellent Mindsqualls Lego Mindstroms Nxt library by Niels K. Handest. It fires of commands to Motorcontrol, a great third party NXC application for better controlling motor movements on the Lego Nxt brick. The robot is connected to the PC using USB. I didn’t try it with the Bluetooth connection yet.

If you are curious about the code, just take a look at the source driving this beast on GitHub. If you just want to see the thing work, enjoy the video below.

P.S. If you like dancing around with some guys, you can also QuickSort like this ;-)

Simple Factory Pattern Example in C#

With the Factory Pattern we provide a clean way to instantiate an object unknown to us at the time of implementation. The only thing we know is the interface of the object with a set of predefined properties and methods we need to use.

In this example we create a Food Factory from a configuration file setting. The factory provides us with the proper kind of food. A call to the Food’s EatIt method shows us a debug message stating the effect this food has on our body. Take a look at the class diagram.

Factory Pattern Food Example ClassDiagram

In our application configuration file we provide the fully qualified type name for the factory we want to use. In this case we go for the FastFood Factory (be honnest).

<applicationSettings>
  <FactoryPatternTests.Properties.Settings>
    <setting name="FoodFactory" serializeAs="String">
      <value>
        FactoryPattern.FoodFactories.FastFoodFactory
      </value>
    </setting>
  </FactoryPatternTests.Properties.Settings>
</applicationSettings>

Let’s write a little test to see the factory pattern in action. In our test we have a method called CreateFoodFactory. This method uses the FoodFactory setting we provided in our app.config. Next we load the FoodFactory assembly by using some magic reflection. Finally we call CreateInstance on this assembly with our factory name. We return the result as an IFoodFactory.

In our main program we can now instantiate some Food Factory, let it create some Food and let us eat it. We do not know or have to know what kind of factory or food we create. We just call on the interfaces.

using System.Linq;
using System.Reflection;
using FactoryPattern.Food;
using FactoryPattern.FoodFactories;
using FactoryPatternTests.Properties;
using Microsoft.VisualStudio.TestTools.UnitTesting;
 
namespace FactoryPatternTests
{
    [TestClass]
    public class FoodFactoryTests
    {
        [TestMethod]
        public void CreateSomeFood()
        {
            IFoodFactory factory = CreateFoodFactory();
            IFood food = factory.CreateFood();
            
            food.EatIt();
        }
 
        private IFoodFactory CreateFoodFactory()
        {
            string factoryName = Settings.Default.FoodFactory.Trim();
            Assembly assembly = Assembly.Load(factoryName.Split('.').First());
            object instance = assembly.CreateInstance(factoryName);
 
            return (IFoodFactory) instance;
        }
    }
}

Factory Pattern Test Result

Using Entity Framework DbSet Local

A DbSet in an Entity Framework DbContext has a Local property that let us access entities already retrieved within the scope of the DbContext. This way it is possible to further query a local entity set, without sending a query to the database. This can lead to highly efficient queries, if you handle it with a little caution.

In the example below we first send a query to the database for all AssemblyItems with a higher price than 10. Before we issue the query back to the database we ask for the AssemblyItem DbSet Local count. Since we did not retrieve any entities, this should be zero.

using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using CodeFirstData;
using CodeFirstPocos;
using Microsoft.VisualStudio.TestTools.UnitTesting;
 
namespace CodeFirstTests
{
    [TestClass]
    public class BomTests
    {
        [TestMethod]
        public void LocalAndDatabaseCountTest()
        {
            using (var bomContext = new BomContext())
            {
                IQueryable<AssemblyItem> query =
                    bomContext.AssemblyItems
                        .Where(ai => ai.Price > 10m);
 
                Debug.WriteLine(
                    "Local count is {0}",
                    bomContext.AssemblyItems.Local.Count);
 

We issue a ToList and we make a roundtrip to the database, retrieving all AssemblyItems we asked for. Again we peek at our Local count. This time we have a total of four AssemblyItems stored in our local cache.

 
                List<AssemblyItem> assemblyItems = query.ToList();
 
                Debug.WriteLine(
                    "Local count is {0}",
                    bomContext.AssemblyItems.Local.Count);
 
                

Lets query the local cache of AssemblyItems and ask for those with a quantity higher than six. Again we take a look at the Local count and see there are two entities that meet our requirements. Note that if we use Local we query against an ObservableCollection type and that the return type is an IEnumerable, not an IQueryable.

 
                IEnumerable<AssemblyItem> localQuery =
                    bomContext.AssemblyItems.Local
                        .Where(ai => ai.Quantity > 6);
 
                Debug.WriteLine(
                    "Local query count is {0}",
                    localQuery.Count());
 

Finally we head back to the database to issue the same query. If we ask for our Local count now, we see there is a row added from the database, making it a total of three. This may be a discrepancy we need to be aware of depending on what we want to achieve while querying the DbSet locally cached entities. With Local we most often query a subset of the rows in the database. If that’s what we want, Local can be our highly-performing friend.

 
                IQueryable<AssemblyItem> dbQuery =
                    bomContext.AssemblyItems
                        .Where(ai => ai.Quantity > 6);
 
                Debug.WriteLine(
                    "Database query count is {0}",
                    dbQuery.Count());
            }
        }
    }
}

Entity Framework Local and Database Count Test

Entity Framework Add Remove Attach and Detach

The DbContext of Entity Framework lets us add, remove, attach and detach entities to and from it. Calling SaveChanges on the DbContext the Entity Framework performs different actions on entities dependant on their EntityState. So an added entity gets inserted, a removed entity gets deleted and so on.

In this example we use the AssemblyItem entity from a previous post to perform some of the most common actions on the entities and DbContext. All the tests below passed.

Add an Entity
To add an entity to the DbContext we instantiate an object of the entity type and call the DbSet Add method. The added entity gets an ‘added’ state. Once we call SaveChanges the entity is saved to the database. The entity now has an ‘unchanged’ state. We call the Entry method on the DbContext to find the state for a given entity.

using System.Data;
using System.Data.Entity;
using CodeFirstData;
using CodeFirstPocos;
using Microsoft.VisualStudio.TestTools.UnitTesting;
 
namespace CodeFirstTests
{
    [TestClass]
    public class BomTests
    {
        [TestMethod]
        public void AddingEntitySetStateToAdded()
        {
            Database.SetInitializer(new DropBomContextIfModelChanges());
            var bomContext = new BomContext();
            AssemblyItem assemblyItem = CreateAssemblyItemStub();
 
            bomContext.AssemblyItems.Add(assemblyItem);
 
            Assert.IsTrue(
                bomContext.Entry(assemblyItem)
                    .State == EntityState.Added);
        }
 
        [TestMethod]
        public void CallingSaveChanesOnAddedEntitySetStateToUnchanged()
        {
            Database.SetInitializer(new DropBomContextIfModelChanges());
            var bomContext = new BomContext();
            AssemblyItem assemblyItem = CreateAssemblyItemStub();
 
            bomContext.AssemblyItems.Add(assemblyItem);
            bomContext.SaveChanges();
 
            Assert.IsTrue(
                bomContext.Entry(assemblyItem)
                    .State == EntityState.Unchanged);
        }
 
        private AssemblyItem CreateAssemblyItemStub()
        {
            const int bomId = 1;
 
            var assemblyItem =
                new AssemblyItem
                    {
                        BillOfMaterialsId = bomId,
                        Description = "Painter's putty",
                        PartNumber = "Glib043",
                        Price = 15.48m,
                        Quantity = 40,
                    };
 
            return assemblyItem;
        }
    }
}

Remove an Entity
If we have an entity we do not longer wish to store in the database we can call Remove on the DbContect for this entity. After this operation the state changes to ‘deleted’. To really delete the entity from the database we need to finally call SaveChanges. After that the entity state is ‘detached’ from the DbContext.

using System.Data;
using System.Data.Entity;
using CodeFirstData;
using CodeFirstPocos;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;
 
namespace CodeFirstTests
{
    [TestClass]
    public class BomTests
    {
        [TestMethod]
        public void RemoveEntitySetStateToDeleted()
        {
            Database.SetInitializer(new DropBomContextIfModelChanges());
            var bomContext = new BomContext();
            AssemblyItem assemblyItem = bomContext.AssemblyItems.First();
 
            Assert.IsTrue(
                bomContext.Entry(assemblyItem)
                    .State == EntityState.Unchanged);
 
            bomContext.AssemblyItems.Remove(assemblyItem);
 
            Assert.IsTrue(
                bomContext.Entry(assemblyItem)
                    .State == EntityState.Deleted);
 
            bomContext.SaveChanges();
 
            Assert.IsTrue(
                bomContext.Entry(assemblyItem)
                    .State == EntityState.Detached);
        }
    }
}

Attach an Entity
If we have an entity which already exists in the database but is somehow unattached from the DbContext we can call Attach on the DbSet to let Entity Framework get back to work with tracking changes. The state after attaching an entity is by default ‘unchanged’.

using System.Data;
using System.Data.Entity;
using CodeFirstData;
using CodeFirstPocos;
using Microsoft.VisualStudio.TestTools.UnitTesting;
 
namespace CodeFirstTests
{
    [TestClass]
    public class BomTests
    {
        [TestMethod]
        public void AttachEntitySetStateToUnchanged()
        {
            Database.SetInitializer(new DropBomContextIfModelChanges());
            var bomContext = new BomContext();
            AssemblyItem assemblyItem = GetDetachedExistingAssemblyItem();
 
            bomContext.AssemblyItems.Attach(assemblyItem);
 
            Assert.IsTrue(
                bomContext.Entry(assemblyItem)
                    .State == EntityState.Unchanged);
        }
 
        private AssemblyItem GetDetachedExistingAssemblyItem()
        {
            using (var bomContext = new BomContext())
            {
                AssemblyItem assemblyItem = bomContext.AssemblyItems.Find(3);
 
                return assemblyItem;
            }
        }
    }
}

Detach an Entity
To explicitly detach an entity from the DbContext we can either take the entity outside of the DbContext scope or call the Detach method on the ObjectContext under the hood of the DbContext.

using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Objects;
using System.Linq;
using CodeFirstData;
using CodeFirstPocos;
using Microsoft.VisualStudio.TestTools.UnitTesting;
 
namespace CodeFirstTests
{
    [TestClass]
    public class BomTests
    {
        [TestMethod]
        public void DetachEntitySetStateToDetached()
        {
            Database.SetInitializer(new DropBomContextIfModelChanges());
            var bomContext = new BomContext();
            AssemblyItem assemblyItem = bomContext.AssemblyItems.First();
 
            ObjectContext objectContext =
                ((IObjectContextAdapter) bomContext).ObjectContext;
 
            objectContext.Detach(assemblyItem);
 
            Assert.IsTrue(
                bomContext.Entry(assemblyItem)
                    .State == EntityState.Detached);
        }
    }
}

Using Entry
A much cleaner way of Adding, Removing, Attaching or Detaching an entity is by using the Entry method of the DbContext. It is smart enough to know to which DbSet the entity belongs and if the entity is already in the database or not (attach or add). You can set the current Entity State in one fell swoop as well. The example below shows an Attach operation and changing the state to ‘modified’.

using System.Data;
using System.Data.Entity;
using CodeFirstData;
using CodeFirstPocos;
using Microsoft.VisualStudio.TestTools.UnitTesting;
 
namespace CodeFirstTests
{
    [TestClass]
    public class BomTests
    {
        [TestMethod]
        public void AttachEntitySetStateToUnchanged()
        {
            Database.SetInitializer(new DropBomContextIfModelChanges());
            var bomContext = new BomContext();
            AssemblyItem assemblyItem = GetDetachedExistingAssemblyItem();
 
            bomContext.Entry(assemblyItem).State = EntityState.Modified;
 
            Assert.IsTrue(
                bomContext.Entry(assemblyItem)
                    .State == EntityState.Modified);
        }
 
        private AssemblyItem GetDetachedExistingAssemblyItem()
        {
            using (var bomContext = new BomContext())
            {
                AssemblyItem assemblyItem = bomContext.AssemblyItems.Find(3);
 
                return assemblyItem;
            }
        }
    }
}

Entity Framework Concurrency Checking with Timestamp

Using a Timestamp column for optimistic concurrency control is quite a common practice in the SQL realm. While doing an insert, update or delete operation the database checks the Timestamp to see if the row has changed since the last time we retrieved it. If not the operation is canceled which eventually causes an exception to be thrown. Entity Framework supports optimistic concurrency checking with a Timestamp field out of the box.

In this example we use the AssemblyItem entity from the Bill Of Materials example. If we want to make sure we don’t save our edits over some other users changes, we need to implement some form of concurrency checking. In this case we do this by using the data annotation attribute Timestamp on the RowVersion property; a byte array.

using System;
using System.ComponentModel.DataAnnotations;
 
namespace CodeFirstPocos
{
    public class AssemblyItem
    {
        public int AssemblyId { get; set; }
        public int BillOfMaterialsId { get; set; }
        public string PartNumber { get; set; }
        public string Description { get; set; }
        public double Quantity { get; set; }
        public decimal Price { get; set; }
        public bool IsInStock { get; set; }
 
        [Timestamp]
        public Byte[] RowVersion { get; set; }
    }
}

This way Entity Framework knows we want to use the RowVersion property for optimistic concurrency control. If we let Entity Framework create our database we see a Timestamp column added to the AssemblyItem table named RowVersion.

Entity Framework Code First Concurrency Control RowVersion

Lets write a test to see optimistic concurrency checking in action. For this we need two different DbContext classes, retrieve the same entity, make some changes to both and call SaveChanges. Since we know the first row is already changed and stored in the database, the call to SaveChanges on the second DbContext for row2 should throw an exception of type DbUpdateConcurrencyException.

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using CodeFirstData;
using CodeFirstPocos;
using Microsoft.VisualStudio.TestTools.UnitTesting;
 
namespace CodeFirstTests
{
    [TestClass]
    public class BomTests
    {
        [TestMethod]
        [ExpectedException(typeof (DbUpdateConcurrencyException))]
        public void ConcurrencyCheckingShouldFailIfTheSameRowIsEditedTwice()
        {
            const int assemblyItemId = 3;
 
            Database.SetInitializer(new DropBomContextIfModelChanges());
            var bomContext1 = new BomContext();
            var bomContext2 = new BomContext();
 
            AssemblyItem row1 = bomContext1.AssemblyItems
                .Single(ai => ai.AssemblyId == assemblyItemId);
            AssemblyItem row2 = bomContext2.AssemblyItems
                .Single(ai => ai.AssemblyId == assemblyItemId);
 
            row1.Quantity += 1;
            row2.Quantity += 10;
 
            bomContext1.SaveChanges();
            bomContext2.SaveChanges();
        }
    }
}

This test passed. So each time the test runs it throws a DbUpdateConcurrencyException when bomContext2 saves its changes. This is because the RowVersion column has changed after storing the edit in bomContext1. In the AssemblyItem table we see the expected incremental changes in the RowVersion column on every save.

Entity Framework Code First Concurrency Control RowVersion Data