LINQ 中的更新查询包含 WHERE 子句中的所有列,而不仅仅是主键列
Update query in LINQ contains all columns in WHERE clause instead of just the primary key column
我正在使用 Linq 更新 table 中的单个列,下面采用虚构的 table。
MyTable(PKID、ColumnToUpdate、SomeRandomColumn)
var row = (from x in DataContext.MyTable
where b.PKID == 5
select x).FirstOrDefault();
row.ColumnToUpdate = 20;
DataContext.SubmitChanges();
这会将列更新为预期的结果,这并不奇怪。但是,当我检查生成的 SQL 命令时,它会这样做:
UPDATE [dbo].[MyTable ]
SET [ColumnToUpdate ] = @p2
WHERE ([PKID] = @p0) AND ([SomeRandomColumn] = @p1)
这是在执行更新,但前提是所有列都与实体期望的值相匹配,而不是单独引用主键列。
如果数据库列被另一个进程更改,这在这个特定项目中是非常可行的;例如。在获取要操作的行、计算要将值设置到的更改以及作为一批行发出更新命令之间存在 window。在这种情况下查询会导致异常,导致部分更新,除非我陷阱,重新加载数据并重新发送个别查询。它也有一个缺点,即行信息可能非常大(例如,包含 HTML 标记),并且整个事情都会传递给 SQL 并在处理较大的批次时减慢系统速度.
有没有办法让 Linq/Entity 仅根据 Where 子句中的 PK 列发出更新命令?
我从未在生产项目中使用过 LINQ-to-SQL,而且我从来不知道它默认应用乐观并发1。
这是默认行为:
- 如果 table 没有
Timestamp/Rowversion
列2,所有 列都有“更新检查”在 DBML 中设置为“始终”(主键列和计算列除外,即所有可更新列)。
- 如果 table 确实有一个
Timestamp/Rowversion
列,则该列在 DBML 中将“时间戳”设置为“真”,并且所有列的“更新检查”=“从不”。
“更新检查”或“时间戳”将列标记为并发标记。这就是为什么在更新语句中您会在(不是这样)“随机”列上看到这些额外的谓词。显然,您模型中的 table 没有 Timestamp/Rowversion
列,因此更新会检查 table.
中所有可更新列的值
1 乐观并发:更新记录时不设置排他锁,更新时检查所有或选定列的现有值。如果其中一个列值在获取数据和保存数据之间被其他用户更改,则会发生更新异常。
2 数据类型 Timestamp
或 Rowversion
的列在更新记录时自动递增,因此会检测对该记录的所有并发更改。
我正在使用 Linq 更新 table 中的单个列,下面采用虚构的 table。
MyTable(PKID、ColumnToUpdate、SomeRandomColumn)
var row = (from x in DataContext.MyTable
where b.PKID == 5
select x).FirstOrDefault();
row.ColumnToUpdate = 20;
DataContext.SubmitChanges();
这会将列更新为预期的结果,这并不奇怪。但是,当我检查生成的 SQL 命令时,它会这样做:
UPDATE [dbo].[MyTable ]
SET [ColumnToUpdate ] = @p2
WHERE ([PKID] = @p0) AND ([SomeRandomColumn] = @p1)
这是在执行更新,但前提是所有列都与实体期望的值相匹配,而不是单独引用主键列。
如果数据库列被另一个进程更改,这在这个特定项目中是非常可行的;例如。在获取要操作的行、计算要将值设置到的更改以及作为一批行发出更新命令之间存在 window。在这种情况下查询会导致异常,导致部分更新,除非我陷阱,重新加载数据并重新发送个别查询。它也有一个缺点,即行信息可能非常大(例如,包含 HTML 标记),并且整个事情都会传递给 SQL 并在处理较大的批次时减慢系统速度.
有没有办法让 Linq/Entity 仅根据 Where 子句中的 PK 列发出更新命令?
我从未在生产项目中使用过 LINQ-to-SQL,而且我从来不知道它默认应用乐观并发1。
这是默认行为:
- 如果 table 没有
Timestamp/Rowversion
列2,所有 列都有“更新检查”在 DBML 中设置为“始终”(主键列和计算列除外,即所有可更新列)。 - 如果 table 确实有一个
Timestamp/Rowversion
列,则该列在 DBML 中将“时间戳”设置为“真”,并且所有列的“更新检查”=“从不”。
“更新检查”或“时间戳”将列标记为并发标记。这就是为什么在更新语句中您会在(不是这样)“随机”列上看到这些额外的谓词。显然,您模型中的 table 没有 Timestamp/Rowversion
列,因此更新会检查 table.
1 乐观并发:更新记录时不设置排他锁,更新时检查所有或选定列的现有值。如果其中一个列值在获取数据和保存数据之间被其他用户更改,则会发生更新异常。
2 数据类型 Timestamp
或 Rowversion
的列在更新记录时自动递增,因此会检测对该记录的所有并发更改。