C# 调用savechanges时Entityframework复制
我首先使用entityframework 5代码,我有一个这样的模型C# 调用savechanges时Entityframework复制,c#,entity-framework,ef-code-first,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 {
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 {
...
}
在调用savechanges之前,调试器中的值是否正确?在调用savechanges之后,调试器中的值是否已更改?知道我为什么会有这种奇怪的行为吗?根据评论中的其他信息:您需要将FabricLineItemID(主键)添加到FabricLineItem类/实体中,并删除FabricId(EF将为您创建一个外键)。创建新的FabricLineItem时,要与产品关联,请从数据库中获取结构记录,然后将其与新创建的FabricLineItem关联,然后获取产品并将其与FabricLineItem关联。您不需要在产品的构造函数中创建新列表,EF将完成其余工作。我怀疑上下文不知道结构不是新项目,因此它会添加/插入它们 如果将结构附加到DataContext(未更改/未修改)-或从数据库中选择它们,则当调用SaveChanges()时,上下文知道现有结构对象,然后可以仅为新FabricLineItem创建导航关系而不创建新结构
EF比它看起来要“愚蠢”得多-你真的需要告诉它几乎所有的事情。我也遇到了E.F.在另一个要添加到DB的新对象中引用某个项时,无法识别该项已经存在的问题 @尼尔·汤普森向我提供了上述解决方法的线索: 您需要将现有实体附加到上下文,以便它知道它已经存在: 例如:
context.Fabrics.Attach(product.Fabric);
context.Products.Add(product);
context.SaveChanges();
return organisation;
我从这里得到这个:
“如果您知道数据库中已经存在一个实体,但该实体当前未被上下文跟踪,那么您可以告诉上下文使用DbSet上的Attach方法跟踪该实体。该实体在上下文中将处于未更改状态。”
为什么在
FabricLineItem
中有FabricId
和virtual Fabric
?不仅仅是虚拟结构
就足够了吗?如何将FabricLineItems
添加到产品
?首先,我只尝试了一下。。但后来我尝试显式设置fabricid,然后尝试保存,但也不起作用。您能告诉我们有关您尝试实现的实际数据模型的更多详细信息吗?什么是FabricLineItem
?你能不能不把面料
与产品
联系起来?实际上,该产品将有一些面料[这些面料类似于原材料],因此我创建了一个fabriclineitem,它将面料链接到产品,并有一些字段,说明产品的哪个部分使用了多少面料。这就是你要问的?你的代码没有你如何保存它的部分。您需要获取结构对象非Id才能保存它。如果未加载结构对象,请仅使用id进行加载。id已存在。。在这里,您可以看到实际的类。你是说我应该先保存产品,然后保存行项目?实际上,我已经将这个模型与视图绑定在一起,这样产品屏幕就可以同时显示行项目列表和其他产品字段。哇,这比我想象的要复杂得多。但是,我认为如果您从FabriLineItem
中丢失了FabricId
,并确保您正在向产品添加一个现有结构(从DB检索到的结构),您应该不会有问题。另外,不要在产品的构造函数中创建新列表。我认为,当您将行项目添加到该列表时,实际上可能是在复制内存中的记录。保存时,EF将更改这些行项目的ID(在DB中创建新记录)。您不需要先保存产品-创建一个新产品,将其添加到新行项目中。这样就可以了。
context.Fabrics.Attach(product.Fabric);
context.Products.Add(product);
context.SaveChanges();
return organisation;