插入具有数据库中存在的一个相关实体的实体

时间:2018-06-30 08:03:46

标签: c# entity-framework-core

当使用Entity Framework Core 2插入具有数据库中已经存在的一个相关实体的新实体时,我陷入了困境。例如,我有两个对象具有一对多关系:

public Class OrderDetail
{
   public int ParentID {get;set;}
   public string OrderDetailName {get;set;}
   public int ProductID {get;set;}
   public virtual Product ProductFK {get;set;}
}

public Class Product
{
   public int ProductID {get;set;}
   public string ProductName {get;set;}
   public virtual Collection<OrderDetail> OrderDetails {get;set;} = new Collection<OrderDetail>();
}

我想将具有现有OrderDetail(带有Product)的新productID = 3添加到数据库中,因此执行如下操作:

private void AddOrderDetail(int productID)
{
    OrderDetail newOrderDetail = new OrderDetail();
    newOrderDetail.Name = "New OrderDetail";

    // Here I have no clue what would be the correct way...Should I do 
    // Approach A(pick related entity from database then assign as related entity to base entity):
    var ProductFromDB = DbContext.Products.SingleOrDefault(p => p.ProductID == productID);
    newOrderDetail.ProductFK = ProductFromDB;

    // Approach B(directly assign the foreign key value to base entity)
    newOrderDetail.ProductID = productID

    DbContext.SaveChange();
} 

通过使用方法(A),我的newOrderDetail无法保存,我查看了SQL资源,看起来它像是我从数据库中检索到的资源({{1} })作为新对象,并尝试再次插入它。我觉得先选择ProductFromDB然后分配给插入的实体是多余的工作...

通过使用方法(B),我的ProductFromDB仍然无法保存,并且出现了一个类似“插入第二个操作的操作,此操作在此操作之前已完成”之类的异常。不能保证任何实例成员都是线程安全的。”,但是,这种异常不会持续发生。我查看了一下SQL并找到了SQL脚本,方法是在SQL Server中单独运行它,然后运行,但是在运行应用程序端时,它不起作用...

那么应对上述情况的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

如果不需要立即访问完整的Product对象,则可以尝试仅设置newOrderDetail的外键列值。另外,在保存之前,您需要将新创建的OrderDetail对象添加到DbContextprivate void AddOrderDetail(int productID) { OrderDetail newOrderDetail = new OrderDetail(); newOrderDetail.Name = "New OrderDetail"; newOrderDetail.ProductID = productID // OF COURSE, you need to ADD the newly created object to the context! DbContext.OrderDetails.Add(newOrderDetail); DbContext.SaveChange(); } -

OrderDetail

下次,当您实际获取using (var DbContext = new YourDbContext()) { OrderDetail od = DbContext.OrderDetails.FirstOrDefault(x => x.Name = "New OrderDetail"); .... } 时,它将解析链接的产品,您应该会好起来。:

par(mfrow = c(2, 2))

plot(1, 1)
plot(1, 1)
plot(1, 1)
plot(1, 1)