插入新实体而不创建子实体(如果存在)
Posted
技术标签:
【中文标题】插入新实体而不创建子实体(如果存在)【英文标题】:Insert a new entity without creating child entities if they exist 【发布时间】:2015-03-02 11:46:44 【问题描述】:我使用的是代码优先的 EF,我有这样的模型:
public class Product
[Key]
public int Id get; set;
[Required]
public string Name get; set;
public Customer Customer get; set;
public class Customer
public Customer ()
Products = new List<Product>();
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id get; set;
// more stuff snipped...
public ICollection<Product> Products get; set;
我收到了客户 ID 以及产品 ID 列表。当数据库中不存在产品时,我想添加它:
var newProduct = new Product Id = id, Name = "<no name yet>", Customer = customer ;
InsertProduct(newProduct);
问题在于 EF 尝试级联更改并尝试插入一个新的 Customer
对象,其 ID 与现有对象相同,因此它失败了。我该如何解决?
这是插入方法:
public void InsertProduct(Product item)
CustomerContext.Entry(item).State = EntityState.Added;
CustomerContext.Set<Product>().Add(item);
【问题讨论】:
【参考方案1】:取自here.
添加具有现有子对象(数据库中存在的对象)的新实体时,如果 EF 未跟踪子对象,则将重新插入子对象。除非您先手动附加子对象。
尝试如下设置子对象状态:
public void InsertProduct(Product item)
// Calling this code before the context is aware of the Child
// objects will cause the context to attach the Child objects to the
// context and then set the state.
// CustomerContext.Entry(childitem).State = EntityState.Unchanged
CustomerContext.Entry(item.ChildObject).State = EntityState.Modified;
CustomerContext.Entry(item).State = EntityState.Added;
CustomerContext.Set<Product>().Add(item);
【讨论】:
【参考方案2】:如果给父类添加外键会更容易:
public class Product
....
public int CustomerId get; set;
public Customer Customer get; set;
然后当你要插入的时候,设置外键而不是导航属性:
var newProduct = new Product
Id = id,
Name = "<no name yet>",
CustomerId = customer.Id
;
InsertProduct(newProduct);
参考资料:
Why does Entity Framework Reinsert Existing Objects into My Database?
Making Do with Absent Foreign Keys
【讨论】:
以上是关于插入新实体而不创建子实体(如果存在)的主要内容,如果未能解决你的问题,请参考以下文章
EF6 vs Entity Framework Core:插入实体而不将主键(身份)重置为零