保存更改后,为什么Entity Framework尝试更新多个行?

时间:2019-05-03 21:52:35

标签: c# entity-framework vue.js asp.net-core entity-framework-core

我有下面的方法,当运行保存更改时,Entity Framework尝试更新多个行吗?即使我只修改一条记录的日期并获取一条记录进行修改。

错误

  

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'属性,因此将尝试更新两行或更多行。

3 个答案:

答案 0 :(得分:1)

仅说明原因:

  1. 您向数据库查询具有特定ID的所有活动用户,然后得出第一个结果。
  2. 实体框架发送请求并将结果具体化为对象。
  3. 您更改属性。
  4. 实体框架将设置对象的状态为已更改。
  5. 您致电SaveChanges,以向EF发出信号,通知其将所做的更改发送回数据库。
  6. 已知对象具有哪个ID,可直接在update语句中对其进行寻址。

这是两个操作:SELECTUPDATE。由于Entity Framework不知道,这些操作是分开执行的:在此期间(直到您叫SaveChanges)您对实体做什么?

为属性分配[ConcurrencyCheck]告诉实体框架,应确保在UPDATE时属性IsActive的值应与{{1}期间的值相同}。当有不同的应用程序写入该数据库时,这可以确保在SELECTSELECT之间的时间内没有其他应用程序更改实体。

您应该删除UPDATE行。或要求他们为“未跟踪”。

答案 1 :(得分:0)

我发现了原因。

在我的实体中,我需要向'IsActive'属性添加数据属性

    [Required]
    [ConcurrencyCheck]
    public bool IsActive { get; set; }

答案 2 :(得分:0)

在我的情况下,该错误是由于没有真实ID列引起的。

我认为是一个ID(在Entity Framework中配置为[Key]属性),在数据库中有重复项,所以即使我使用它进行过滤,我也会更新多行。