繁体   English   中英

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

[英]Entity framework - Check if entry exists before insertion and 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();

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

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

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

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

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

这是我的选择:

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

这就是这种情况……我想知道是否存在针对此特定情况的任何方法或“模式”,或者我是否应该针对上述“解决方案”之一?


编辑令我非常不幸的是,该系统的制作方式非常有问题...(不是我的,嘿嘿)T_T

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

这就是为什么我需要遍历循环以仅更新我需要的字段(这意味着除提到的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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM