首页 > 解决方案 > 为什么在我保存更改时实体框架会尝试更新多行?

问题描述

我有下面的方法,当运行保存更改时,实体框架会尝试更新多行?即使我只修改一条记录上的日期并获取一条记录进行修改。

错误

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException:数据库操作预计会影响 1 行,但实际上会影响 2 行。自加载实体以来,数据可能已被修改或删除。

方法

    public static async Task<HttpResult> PostRecordCoworkerStartDateAsync(MpidDbContext context, int id, RecordCoworker recordCoworker)
    {
        // just testing to see how many are returned
        int testCount = context.RecordsCoworkers.Where(m => m.Id == id && m.IsActive == true).ToList().Count();

        RecordCoworker recordCoworkerToUpdate = context.RecordsCoworkers.SingleOrDefault(m => m.Id == id && m.IsActive == true);

        recordCoworkerToUpdate.StartDate = recordCoworker.StartDate;

        try
        {
            await context.SaveChangesAsync();
        } catch(Exception ex)
        {
            var i = ex;
        }

        return HttpResult.NoContent;
    }

不知何故,当查询运行时,它会剔除需要正确更新的参数,例如。'IsActive' 字段。我已经捕获了下面的查询。

SET NOCOUNT ON;
UPDATE [Records_Coworkers] SET [StartDate] = @p0
WHERE [RecordID] = @p1 AND [CoworkerID] = @p2;
SELECT @@ROWCOUNT;

基本上,我只想更新“IsActive”为真的一条记录。但是查询,因为它去掉了“IsActive”属性,所以会尝试更新两行或多行。

标签: c#entity-frameworkvue.jsasp.net-coreentity-framework-core

解决方案


只是为了解释原因:

  1. 您向数据库询问具有特定 ID 的所有活动用户并获取第一个结果。
  2. 实体框架发送请求并将结果具体化为一个对象。
  3. 你改变财产。
  4. 实体框架会将对象的状态设置为已更改。
  5. 您调用SaveChanges以向 EF 发出信号,表明它将更改发送回数据库。
  6. 由于知道对象具有哪个 id,因此直接在更新语句中对其进行寻址。

这是两个操作:SELECTUPDATE。这些是单独执行的,因为实体框架不知道:您在此期间(直到您调用SaveChanges)对实体做了什么?

分配[ConcurrencyCheck]给属性会告诉 Entity Framework,它应该确保UPDATE属性的值IsActiveSELECT. 当有不同的应用程序写入该数据库时,这可确保在SELECT和之间没有其他应用程序更改实体UPDATE

您应该删除该int testCount行。或将它们请求为未跟踪。


推荐阅读