LINQ 更新过程 - 最佳实践
Posted
技术标签:
【中文标题】LINQ 更新过程 - 最佳实践【英文标题】:LINQ update procedures - best practice 【发布时间】:2011-03-16 06:16:17 【问题描述】:在使用 LINQ 时,什么是更新的最佳实践:
拥有实例化的数据库/外观 对象,并将所有更改提交给 一口气录制? 要有一个静态的 db/facade 对象, 并逐个提交更改?现在我在一个项目中,记录的每个单元格都有自己的静态更新方法
public static void CellName(int id, int data)
using (var scope = new someDataContext())
var TableName = scope. CellName.Single(v => v.ID == id);
TableName.CellName = data;
scope.SubmitChanges();
然后可以按照通常的TableName.CellName = [something]
方案将这些设置为业务对象中的属性。
但我也做过使用实例化 db/facade 类的项目。您首先设置新值(如属性),然后调用 database.SubmitChanges()
方法,然后对整个记录(或记录)进行更新。
从设计的角度来看,我更喜欢第一个选项 - 设置属性时,更改是即时的,并且它被视为任何其他对象。但从技术角度来看,我怀疑通过批量更新可以获得性能。
那么我应该选择哪种方法 - 还是我应该考虑其他选择?
【问题讨论】:
【参考方案1】:更新单个单元格的效率极低。更新数据库的主要开销是实例化连接、发送和接收回复以及在表中查找要更新的行。如果您更新每个单元格,那么您需要对每个单元格执行这些步骤 - 如果您更新每行,那么它是每行一次。
单独更新单元格相当于编写 SQL 之类的
-- new command
UPDATE [Table] SET [Column1] = 'Value1' WHERE [Id] = 1
GO
-- new command
UPDATE [Table] SET [Column2] = 'Value2' WHERE [Id] = 1
GO
-- new command
UPDATE [Table] SET [Column3] = 'Value3' WHERE [Id] = 1
GO
命令是串行处理的,每个命令都等到前一个命令完成后再执行。虽然这可能不会比一次更新整行慢很多,但它可能会更慢,而且绝对不会更快。
首选方法是一次更新所有属性,然后发送一条 SQL 命令。
UPDATE [Table]
SET [Column1] = 'Value1', [Column2] = 'Value2', [Column3] = 'Value3'
WHERE [Id] = 1
这涉及到几个步骤,如果您从物理上和实践上考虑它,这一切都应该是有意义的。
首先,LINQ-to-SQL 检索整行,以便您可以更新属性。 'per cell' 或 'per row' 操作都需要这样做,所以花费的时间是一样的。
// the "Single" operator retrieves an entire row
var TableName = scope.CellName.Single(v => v.ID == id);
var row = scope.MyTable.Single(v => v.Id == id); // more accurate description
-- sql looks something like this
SELECT TOP 1 * FROM [MyTable] WHERE [Id] = @id
这涉及
编译查询 打开连接/从池中检索连接 将命令发送到 SQL 服务器 收到来自 SQL 服务器的回复与另一台服务器通信可能需要几毫秒到几秒不等,具体取决于距离、性能、服务器负载等。
然后您更新一个属性。
row.Column1 = data;
这仅需要循环。它是整个操作时间的一个不可估量的小组成部分。
然后您提交更改。
scope.SubmitChanges();
-- sql looks like this
UPDATE [MyTable] SET /* set of columns to update */ WHERE [Id] = @id
这又涉及到许多步骤
编译查询 将命令发送到 SQL Server 接收来自 SQL Server 的响应单独更新单元格并没有“即时”的功能 - 单元格将在更新的同时使用“每行”模式更新整行。只是剩余的单元格需要更长的时间来更新。
不仅如此,从您的问题的外观来看,您还将拥有数百个样板文件 UpdateProperty
方法。我以前从未见过或听说过这样的模式,但老实说,这听起来很糟糕——你发送的 SQL 命令比必要的多很多倍,而且你的数据库延迟乘以表中的列数。
【讨论】:
以上是关于LINQ 更新过程 - 最佳实践的主要内容,如果未能解决你的问题,请参考以下文章
用于检查字符串列表/数组中的字符串的 C# 最佳实践 (LINQ) [关闭]