C# DBContext结合原生SQL实现SQL Server按条件批量更新多行数据
问题解答
1. SQL Server能否用单条语句实现需求
可以,两个需求都可以通过单条UPDATE语句结合CASE表达式实现,无需拆分多条SQL执行。
2. 对应SQL语句及C#调用方式
前置说明
注意你的EF配置中表映射为TestSelecters,SQL建表语句写的是Selecters,以下示例以EF配置的TestSelecters为准,实际使用请替换为你真实的表名。
需求1实现(单选选中逻辑)
SQL语句
UPDATE TestSelecters SET Selected = CASE WHEN SelecterId = @TargetSelecterId THEN 1 ELSE 0 END
C#调用
执行更新优先使用ExecuteSqlRaw(性能更高,无需返回实体时首选):
// 替换为你要选中的行的SelecterId string targetId = "fruit0"; // 参数化传值避免SQL注入 int affectRows = context.Database.ExecuteSqlRaw(@" UPDATE TestSelecters SET Selected = CASE WHEN SelecterId = {0} THEN 1 ELSE 0 END", targetId);
如果需要通过FromSqlRaw返回更新后的所有实体数据,可配合OUTPUT子句:
string targetId = "fruit0"; var allSelecters = context.Selecters.FromSqlRaw(@" UPDATE TestSelecters SET Selected = CASE WHEN SelecterId = {0} THEN 1 ELSE 0 END OUTPUT inserted.*", targetId).ToList();
需求2实现(UniqueText唯一逻辑)
SQL语句
UPDATE TestSelecters SET UniqueText = CASE WHEN SelecterId = @TargetSelecterId THEN @NewUniqueText WHEN UniqueText = @NewUniqueText THEN N'' ELSE UniqueText END
C#调用
优先使用ExecuteSqlRaw:
// 替换为你要修改的行的SelecterId string targetId = "fruit3"; // 替换为要设置的新UniqueText值 string newText = "lemon"; int affectRows = context.Database.ExecuteSqlRaw(@" UPDATE TestSelecters SET UniqueText = CASE WHEN SelecterId = {0} THEN {1} WHEN UniqueText = {1} THEN N'' ELSE UniqueText END", targetId, newText);
需要返回更新后实体的FromSqlRaw写法:
string targetId = "fruit3"; string newText = "lemon"; var allSelecters = context.Selecters.FromSqlRaw(@" UPDATE TestSelecters SET UniqueText = CASE WHEN SelecterId = {0} THEN {1} WHEN UniqueText = {1} THEN N'' ELSE UniqueText END OUTPUT inserted.*", targetId, newText).ToList();
注意事项
- 所有传值均使用EF Core内置的参数化逻辑,禁止手动拼接SQL字符串,避免SQL注入风险。
- 若你的业务场景需要更高的并发安全性,可在SQL语句末尾加
WITH (UPDLOCK, HOLDLOCK)锁提示避免并发冲突。
内容的提问来源于stack exchange,提问作者joseluisbz
相关产品推荐
相关产品推荐

