【发布时间】:2015-01-07 07:10:21
【问题描述】:
我目前在 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,看看它的值是否为空,创建一个对象或者使用Find语句。但是,如果可能的话,我不想在我的代码中添加更多逻辑
- 我可以在创建新对象时生成一个临时唯一 ID。但这在我看来不是很干净。
情况就是这样...我想知道对于这种特定情况是否存在任何方法或“模式”,或者我是否应该针对上述“解决方案”之一?
编辑 不幸的是,这个系统的制作方式非常可疑……(不是我做的,呵呵)T_T
为简单起见,每次进行更改时都会更新两个字段:updated_by 和 last_updated。 这意味着每当您要保存数据时,updated_by 字段都与数据库中的值不同。因此,每当您保存数据时,所有对象都被视为已修改,因为该字段已更新。
这就是为什么我需要通过一个循环来仅更新我需要的字段(这意味着除了提到的 2 个字段之外的所有字段)。
【问题讨论】:
标签: c# mysql insert entity-framework-6 auto-increment