我有下面的方法,当运行保存更改时,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'属性,因此将尝试更新两行或更多行。
答案 0 :(得分:1)
仅说明原因:
SaveChanges
,以向EF发出信号,通知其将所做的更改发送回数据库。这是两个操作:SELECT
和UPDATE
。由于Entity Framework不知道,这些操作是分开执行的:在此期间(直到您叫SaveChanges
)您对实体做什么?
为属性分配[ConcurrencyCheck]
告诉实体框架,应确保在UPDATE
时属性IsActive
的值应与{{1}期间的值相同}。当有不同的应用程序写入该数据库时,这可以确保在SELECT
和SELECT
之间的时间内没有其他应用程序更改实体。
您应该删除UPDATE
行。或要求他们为“未跟踪”。
答案 1 :(得分:0)
我发现了原因。
在我的实体中,我需要向'IsActive'属性添加数据属性
[Required]
[ConcurrencyCheck]
public bool IsActive { get; set; }
答案 2 :(得分:0)
在我的情况下,该错误是由于没有真实ID列引起的。
我认为是一个ID(在Entity Framework中配置为[Key]属性),在数据库中有重复项,所以即使我使用它进行过滤,我也会更新多行。