Quantcast
Channel: Entity Framework
Viewing all articles
Browse latest Browse all 10318

Commented Issue: DetectChanges() throws "An item with the same key has already been added." exception after setting a complex type property [1278]

$
0
0
Hi,

In Beta 1 the DbContext.ChangeTracker.DetectChanges() throws "An item with the same key has already been added." exception after setting a complex type property.

See the following code which reproduces the issue. The context.ChangeTracker.DetectChanges() line is the one to look for.

It would be great if it is looked at as soon as possible as it is a blocking issue for me.

Thanks

Regards

Iouri


using System;
using System.Linq;

namespace EF6b1.ComplexProperty.Bug
{
public class ComplexType
{
public virtual int? Value1 { get; set; }
public virtual int? Value2 { get; set; }
}

public class Entity
{
public virtual Guid Id { get; set; }
public virtual ComplexType ComplexProperty { get; set; }
}

public class DbContext : System.Data.Entity.DbContext
{
public DbContext(string connectionString) : base(connectionString) { }
public virtual System.Data.Entity.IDbSet<Entity> Entities { get; set; }
}


class Program
{
static DbContext CreateDbContext()
{
return new DbContext(@"Data Source=(local)\sql2012;Initial Catalog=EF6b1.ChangeTrackingBug;Integrated Security=True;MultipleActiveResultSets=True");
}
static void Main(string[] args)
{
try
{
using (var context = CreateDbContext())
{
var entity = context.Entities.Create();
context.Entities.Add(entity);
entity.Id = Guid.NewGuid();

//(IS) at the moment EF requires the complex type proeprties to be explicitly set to non-null values - I dont think it's right
entity.ComplexProperty = new ComplexType();

context.SaveChanges();
}

using (var context = CreateDbContext())
{
var entity = context.Entities.Take(1).First();

entity.ComplexProperty = new ComplexType();

//(IS) this will fail with "An item with the same key has already been added." exception originating in EntityEntry.ExpandComplexTypeAndAddvalues()
context.ChangeTracker.DetectChanges();
}

Console.WriteLine("Finished with no errors.");
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}

Console.WriteLine("Press any key to exit...");
Console.ReadKey(true);
}
}
}

Comments: Fixed in 0a2bf3c5a2f8 Not so complex after all... (Fix for 1278: DetectChanges throws when changing complex property instance on change tracking proxy) This was a regression introduced post alpha 3 by a change to optimize original value tracking in the state manager. The problem is that when a complex object instance is changed in a change tracking proxy the change is updated immediately in the state manager. However, this was not taken into account by DetectChanges which then detected the snapshot difference and tried to make the same change again. It might be possible to have DetectChanges not process complex object instance changes when change tracking proxies are being used, but this is not straightforward code and I am not confident that it would a) work b) have any significant benefit and c) not introduce more regressions. Therefore, the simple fix here is to make the new optimized code behave in the same way as it always has--that is, allow DetectChanges to make the change even though it has already been recorded.

Viewing all articles
Browse latest Browse all 10318

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>