实体框架在调用savechanges时重复

时间:2013-03-13 19:04:36

标签: c# entity-framework ef-code-first

我首先使用entityframework 5代码,我有一个这样的模型。

class Product {
    public Product() {
        Fabrics = new BindingList<FabricLineItem>();
    }
    ...
    public virtual ICollection<FabricLineItem> Fabrics { get;set; }
}

class FabricLineItem {
    [ForeignKey("Fabric")]
    public int FabricId { get; set; }  
    public virtual Product Product { get;set; }
    public virtual Fabric Fabric { get;set; }  
}

class Fabric {
    ...
}

我的数据库中已有面料。我创建了一个新的产品对象,并为该集合添加了一些fabriclineitems。当我尝试保存产品时会发生什么,它会复制数据库中的结构并在调用后将其引用到新结构

 DataContext.SaveChanges(); 

在调用savechanges之前,在调用它们之后,调试器中的值是否正确?知道为什么我会得到这种奇怪的行为吗?

3 个答案:

答案 0 :(得分:11)

我也遇到了E.F.的问题,当在另一个要添加到数据库中的新对象中引用某个项目时,该项目已经存在。

@NeilThompson给了我如何解决这个问题的线索:

您需要将现有实体附加到上下文,以便它知道它已经存在:

例如:

context.Fabrics.Attach(product.Fabric); 
context.Products.Add(product);
context.SaveChanges();

return organisation;

我从这里得到了这个:

&#34;如果您知道某个实体已存在于数据库中但当前未被上下文跟踪,那么您可以告诉上下文使用DbSet上的Attach方法跟踪实体。该实体在上下文中将处于Unchanged状态。&#34;

http://blogs.msdn.com/b/adonet/archive/2011/01/29/using-dbcontext-in-ef-feature-ctp5-part-4-add-attach-and-entity-states.aspx

答案 1 :(得分:6)

我怀疑上下文不知道Fabrics不是新项目 - 所以它添加/插入它们。

如果将结构附加到DataContext(作为Unchanged / NotModified) - 或者从数据库中选择它们,那么当调用SaveChanges()时,上下文知道现有的Fabric对象,然后可以为新的Fabric对象创建导航关系FabricLineItem无需创建新的Fabric

EF很多'笨蛋'而不是它看起来 - 你真的需要告诉它几乎所有东西。

答案 2 :(得分:0)

根据评论中的其他信息:您需要将FabricLineItemID(主键)添加到FabricLineItem类/实体并删除FabricId(EF将为您创建外键)。创建新的FabricLineItem时,要与Product关联,从数据库获取Fabric记录,然后将其与新创建的FabricLineItem关联,然后获取产品并将其与FabricLineItem关联。您不需要在Product的构造函数中创建新列表,EF将完成剩下的工作。