实体框架 - 在插入和自动增加之前检查条目是否存在

时间:2014-11-10 21:06:18

标签: c# mysql insert entity-framework-6 auto-increment

我目前在EF中保存数据的过程中遇到了一个小问题。 我试图在一个事务中使用自动递增的字段插入或更新多行。

这是我的代码:

var Orders = ctx.Orders;
foreach (var order in ordersForm)
{
    var OrderEntity = Orders.Find(order.orderId);
    if (OrderEntity == null)
    {
        OrderEntity = new Order();
    }

    OrderEntity.Name = order.name;
    OrderEntity.Date = DateTime.Now;
    ...

    // If no order in the set --> add order
    if (!Orders.Local.Any(e => e == OrderEntity))
    {
        Orders.Add(OrderEntity);
    }
    if (ctx.Entry(Order).State == EntityState.Added 
       || ctx.Entry(Order).State == EntityState.Modified)
    {
        OrderEntity.DateModified = DateTime.Now;
        OrderEntity.LastUpdatedBy = Session["user"].ToString();
    }
    ...
}
ctx.SaveChanges();

所以我试图从db或缓存中获取一个实体:

  • 如果它存在,那么我更新它
  • 如果没有,那么我创建一个新的,我在设置属性后添加到上下文中。调用SaveChanges()后,id将在数据库级别递增。

请注意,由于我没有调用SaveChanges方法,因此我新添加的实体将具有空ID。

当我第二次迭代并且我必须创建另一个对象时出现问题:

  • 如果我调用Find方法,它将返回上一次迭代中添加的实体。因为ID将是相同的(null)。结果是我之前创建的对象将被当前创建的对象覆盖。

以下是我的选择:

  • 我知道我可以通过使用Where而不是Find来避免这个问题,但这不是一个选项,因为它应该通过首先请求商店来节省资源。
  • 我可以首先检查表单提供的Id,以及它的值是否为null创建对象或使用Find语句。但是,如果可能的话,我不想在我的代码中添加更多逻辑
  • 我可以在创建新对象时生成临时唯一ID。但我认为这不是很干净。

这种情况......我想知道是否有任何方法或"模式"这是针对这种特殊情况而存在的,或者我应该针对其中一个解决方案"上面提到过?


EDIT 令我非常不幸的是,这个系统是以一种非常可疑的方式制作的......(不是我,嘿嘿)T_T

为简单起见,每次更改时都会更新两个字段:updated_by和last_updated。 这意味着无论何时要保存数据,updated_by字段都与数据库中的值不同。因此,每当您保存数据时,所有对象都被视为已修改,因为此字段已更新。

这就是为什么我需要通过一个循环来仅更新我需要的字段(这意味着除了提到的2之外的所有字段)。

1 个答案:

答案 0 :(得分:2)

出于好奇,为什么不在哪里?我个人会这样做,将更新项目和添加项目分成两个列表,使用添加范围同时添加所有新项目。

var newitems = ordersform.Where(i=> Orders.All(ii=>ii != i);
var updateItems = ordersform.Where(i=> Orders.Any(ii=> ii==i);
updateItems.Foreach(i => {Update Item};
Orders.AddRange(newItems);
ctx.SaveChanges();
相关问题