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) [关闭]

维护不同 Worklight Studio 补丁程序版本的最佳实践

SQL Server 2008 架构更改的最佳实践

更新片段参数的最佳实践?

RESTful 服务中部分更新的最佳实践

Laravel 中批量更新关系的最佳实践