插入新实体而不创建子实体(如果存在)

本文关键字:实体 如果 存在 创建 新实体 插入 | 更新日期: 2024-09-21 08:56:38

我首先使用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);
    }

插入新实体而不创建子实体(如果存在)

取自此处。

添加具有现有子对象(数据库中存在的对象)的新实体时,如果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);
}

如果将外键添加到父类中会更容易:

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);

参考文献:

为什么实体框架将现有对象重新插入我的数据库?

凑合着用没有的外键