I’m using Entity Framework 5.0 (for .NET 4) and making use of the TimestampAttribute for optimistic concurrency checking. However I’m seeing strange/unexpected behavior where the version/timestamp of parent entities are updated as a result only of their children being updated.
This is best explained through example code.
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Linq;
namespace ConsoleApplication1
{
public abstract class Entity
{
public int Id { get; set; }
public string Name { get; set; }
/*[ConcurrencyCheck]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Column(TypeName = "rowversion")]*/
[Timestamp]
public byte[] Version { get; set; }
}
public class Parent : Entity
{
public virtual List<Child> Children { get; set; }
}
public class Child : Entity
{
public virtual Parent Parent { get; set; }
// Uncommenting property below causes the parent version to be unexpectedly updated when its child is updated.
// This occurs regardless of whether the Version property is decorated with [Timestamp] or [ConcurrencyCheck].
//public int? ParentId { get; set; }
}
public class TestDbContext : DbContext
{
public DbSet<Parent> Parents { get; set; }
public DbSet<Child> Children { get; set; }
}
internal class Program
{
private static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<TestDbContext>());
var child = new Child {Name = "Child"};
var parent = new Parent {Name = "Parent", Children = new List<Child> {child}};
using (var context = new TestDbContext())
{
context.Parents.Add(parent);
context.SaveChanges();
var originalParentVersion = parent.Version.ToArray();
child.Name = "New Child Name";
context.SaveChanges();
if (!originalParentVersion.SequenceEqual(parent.Version))
throw new Exception("Not expected");
}
Console.Write("Press any key to exit.");
Console.ReadKey();
}
}
}
If I run this simple console application as is, the ‘Not expected’ exception is not thrown. However, if I uncomment the ID foreign key property (ParentID) then the exception will be thrown.
Can anyone explain this strange behavior? Is this a bug?
The description seems to match an issue in EF4 for which we released a hotfix:
FIX: The principal entity in an SQL application generates unnecessary updates when the application uses the Entity Framework in the .NET Framework 4
There is no direct download link for the hotfix so you will have to follow some instructions to obtain it. Otherwise the fix is also included in .NET 4.5.