c# - 为什么在我保存更改时实体框架会尝试更新多行?
问题描述
我有下面的方法,当运行保存更改时,实体框架会尝试更新多行?即使我只修改一条记录上的日期并获取一条记录进行修改。
错误
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”属性,所以会尝试更新两行或多行。
解决方案
只是为了解释原因:
- 您向数据库询问具有特定 ID 的所有活动用户并获取第一个结果。
- 实体框架发送请求并将结果具体化为一个对象。
- 你改变财产。
- 实体框架会将对象的状态设置为已更改。
- 您调用
SaveChanges
以向 EF 发出信号,表明它将更改发送回数据库。 - 由于知道对象具有哪个 id,因此直接在更新语句中对其进行寻址。
这是两个操作:SELECT
和UPDATE
。这些是单独执行的,因为实体框架不知道:您在此期间(直到您调用SaveChanges
)对实体做了什么?
分配[ConcurrencyCheck]
给属性会告诉 Entity Framework,它应该确保UPDATE
属性的值IsActive
在SELECT
. 当有不同的应用程序写入该数据库时,这可确保在SELECT
和之间没有其他应用程序更改实体UPDATE
。
您应该删除该int testCount
行。或将它们请求为未跟踪。
推荐阅读
- asp.net-core - Razor 中的 C# 视图输出为字符串文字
- jsf - 如何将内容呈现为纯文本和 URL 编码
- substrate - 可以在基材中使用字符串吗?
- vue.js - 有没有办法替换 Nuxt 中特定模板的基本路径?
- java - Mockito - 多次调用的嵌套方法
- validation - 如何使用 go-playground 验证器在嵌入式结构上运行自定义验证函数
- javascript - 无法从 @typeform/embed 获取 createSlider 以在 React 中工作
- python-3.x - 1064,“您的 SQL 语法有错误 | PyMySQL 更新过程出现错误
- github - 如何使用 IntelliJ/RubyMine/etc 管理多个 GitHub 帐户
- r - 在部署包含库 rsconnect 的 Shiny App 时面临问题