2014-03-30 34 views
2

我正在使用实体框架6,代码优先的方法。我会尽力提出我的问题,一段简单的代码:未能附加分离的实体(具有相同密钥的实体已经在上下文中)

public void ViewEntity(MyEntity Entity) // Want to read properties of my entity 
{ 
    using (var Db = new MyDbContext()) 
    { 
     var DummyList = Db.MyEntities.ToList(); // Iteration on this DbSet 
     Db.MyEntities.Attach(Entity); // Exception 
    } 
} 

异常消息为:连接类型“MyProgram.MyEntity”的实体失败,因为同类型的另一实体已经具有相同的主核心价值。

从我在MSDN上读到的这是一个预期的行为。但是我最后想要的是首先检查是否有一个实体具有与上下文相同的密钥;如果是这样,请改用它,并且仅以其他方式将我的实体附加到上下文。

但我没有找到办法。 ObjectContext实例上有许多实用方法(例如GetObjectByKey)。我不能全部测试它们,因为它们都最终需要一个qualifiedEntitySetName,而我没有任何实际的imlpementation,因为这个方法应该在抽象类上,它应该适用于所有实体类型。调用Db.Entity(this)是没有用的,没有EntityKey会有EntitySetName。

因此,所有这些变得非常复杂。用我的话来说,我只想检查对象是否已经在“缓存”(上下文)中,使用它,否则使用我的对象并将其附加到此上下文中。

为了清楚起见,我首先从TreeNode.Tag中分离了一个对象,并且我只是想再次使用它,或者如果它不可能的话;如果在上下文中已经有一个),请改用那个。也许我错过了EF6的一些关键概念,我刚刚开始使用EF。

+0

你可以看看我的[ASP.NET MVC的答案 - 附加型“MODELNAME”的实体失败,因为另一个实体相同的类型已具有相同的主键值](http://stackoverflow.com/questions/23201907/asp-net-mvc-attaching-an-entity-of-type-modelname-failed-because-another-ent/ 39557606#39557606)。 –

回答

0

我找到了解决方案。正如我猜对了ObjectContext.GetObjectByKey方法做我需要的,但首先我需要构造qualifiedEntitySetName,并且我找到了一种方法来做到这一点。有点麻烦(使用反射,MyDbContext的迭代属性),但不能比较我所做的一个问题的头痛。为以防万一,这里的代码的补丁,对我来说是一个解决方案:

public SdsAbstractObject GetAttachedToContext() 
{ 
    var ObjContext = (SdsDbContext.Current as IObjectContextAdapter).ObjectContext; 
    var ExistingItem = ObjContext.GetObjectByKey(GetEntityKey()) as SdsAbstractObject;  
    if (ExistingItem != null) 
     return ExistingItem; 
    else 
    { 
     DbSet.Attach(this); 
     return this; 
    } 
} 

public EntityKey GetEntityKey() 
{ 
    string DbSetName = ""; 
    foreach (var Prop in typeof(SdsDbContext).GetProperties()) 
    { 
     if (Prop.PropertyType.IsGenericType 
      && Prop.PropertyType.GenericTypeArguments[0] == ObjectContext.GetObjectType(GetType())) 
      DbSetName = Prop.Name; 
    } 
    if (String.IsNullOrWhiteSpace(DbSetName)) 
     return null; 
    else 
     return new EntityKey("SdsDbContext." + DbSetName, "Id", Id); 
} 
0

实体可处于五个阶段之一:已添加,未更改,已修改,已删除,已分离。

public void ViewEntity(MyEntity entity) // Want to read properties of my entity 
{ 
    using (var Db = new MyDbContext()) 
    { 
     var DummyList = Db.MyEntities.ToList(); // Iteration on this DbSet 
     // Set the Modified state of entity or you can write defensive code 
     // to check it before set the state. 
     if (Db.Entry(entity).State == EntityState.Modified) { 
      Db.Entry(entity).State = EntityState.Modified 
     } 

     // Attached it 
     Db.MyEntities.Attach(Entity); 

     Db.SaveChanges(); 
    } 
} 

由于EF不知道哪些属性与数据库中的属性不同,因此它们将全部更新它们。

+0

它没有帮助。当Db.Entry(entity).State行执行时,即使在“Attach”行之前,它也立即给出相同的错误。但我找到了一个解决方案。不是很漂亮,但它的作品。为了防止像我这样的新手需要它,我已经发布了一个对我自己的问题的答案。 – evilkos

相关问题