问题描述及重现代码:
假设有TestEntity表,实体定义如下:
public class TestEntity
{
[Column(IsPrimary = true, IsIdentity = true)]
public int Id { get; set; }
public int Key { get; set; }
public int Year { get; set; }
public int Count { get; set; }
}
现需要实现逻辑:创建一个实例,如果表中没有则插入新行;否则将表中命中的行Count列加1。
很容易写出以下代码:
var statEntity = new TestEntity()
{
Key = 1,
Year = 2026
};
var sql = freeSql.InsertOrUpdate<TestEntity>()
.SetSource(statEntity, p => new { p.Key })
.UpdateSet((a, b) => a.Count == a.Count + 1)
.ToSql();
但实际生成的SQL是:
MERGE INTO [TestEntity] t1
USING (SELECT 0 as [Id], 1 as [Key], 2026 as [Year], 0 as [Count] ) t2 ON (t1.[Key] = t2.[Key])
WHEN MATCHED THEN
update set [Year] = t2.[Year], [Count] = (t1.[Count] + 1) -- Year被更新为2026!
WHEN NOT MATCHED THEN
insert ([Key], [Year], [Count])
values (t2.[Key], t2.[Year], t2.[Count]);
调整代码v1:
var sql = freeSql.InsertOrUpdate<TestEntity>()
.SetSource(statEntity, p => new { p.Key })
.UpdateSet((a, b) => a.Count == a.Count + 1)
.UpdateColumns(a => a.Count)
.ToSql();
SQL符合预期:
MERGE INTO [TestEntity] t1
USING (SELECT 0 as [Id], 1 as [Key], 2026 as [Year], 0 as [Count] ) t2 ON (t1.[Key] = t2.[Key])
WHEN MATCHED THEN
update set [Count] = (t1.[Count] + 1)
WHEN NOT MATCHED THEN
insert ([Key], [Year], [Count])
values (t2.[Key], t2.[Year], t2.[Count]);
调整代码v2:
var sql = freeSql.InsertOrUpdate<TestEntity>()
.SetSource(statEntity, p => new { p.Key })
.UpdateSet((a, b) => a.Count == a.Count + 1)
.UpdateColumns(a => a.Year) // 故意为之
.ToSql();
SQL:
MERGE INTO [TestEntity] t1
USING (SELECT 0 as [Id], 1 as [Key], 2026 as [Year], 0 as [Count] ) t2 ON (t1.[Key] = t2.[Key])
WHEN MATCHED THEN
update set [Year] = t2.[Year], [Count] = (t1.[Count] + 1) -- UodateColumn约束失效
WHEN NOT MATCHED THEN
insert ([Key], [Year], [Count])
values (t2.[Key], t2.[Year], t2.[Count]);
调整UpdateColumns和UpdateSet顺序,对结果没有影响。
以上行为实在让人困惑,尤其文档中没有明确UpdateColumn和UpdateSet的组合关系,极易让开发者误会导致数据被错误覆盖。
数据库版本
SqlServer 2016
安装的Nuget包
3.5.309
.net framework/. net core? 及具体版本
.NET 10
问题描述及重现代码:
假设有TestEntity表,实体定义如下:
现需要实现逻辑:创建一个实例,如果表中没有则插入新行;否则将表中命中的行Count列加1。
很容易写出以下代码:
但实际生成的SQL是:
调整代码v1:
SQL符合预期:
调整代码v2:
SQL:
调整UpdateColumns和UpdateSet顺序,对结果没有影响。
以上行为实在让人困惑,尤其文档中没有明确UpdateColumn和UpdateSet的组合关系,极易让开发者误会导致数据被错误覆盖。
数据库版本
SqlServer 2016
安装的Nuget包
3.5.309
.net framework/. net core? 及具体版本
.NET 10