LINQ to SQL更新

时间:2009-05-23 13:27:00

标签: sql linq linq-to-sql

有没有人知道如何使用LINQ运行以下语句?

UPDATE FileEntity SET DateDeleted = GETDATE() WHERE ID IN (1,2,3)

我既爱又恨LINQ,但到目前为止,一直没有那么好用。我想避免的一个明显的解决方案是枚举所有文件实体并手动设置它们。

foreach (var file in db.FileEntities.Where(x => ids.Contains(x.ID)))
{
    file.DateDeleted = DateTime.Now;
}
db.SubmitChanges();

上面的代码存在问题,除了相当大的开销是每个实体都有一个可能相当大的数据字段,因此对于大型更新,许多数据在没有特殊原因的情况下跨数据库连接运行。 (LINQ解决方案是延迟加载Data属性,但如果有一些方法只使用LINQ to SQL更新字段,则不需要这样做。)

我正在考虑一些会导致上述T-SQL的查询表达式提供程序...

2 个答案:

答案 0 :(得分:2)

LINQ无法在商店更新中执行 - 它是语言集成查询,而不是更新。大多数(甚至可能是全部)OR映射器将生成一个select语句来获取数据,在内存中修改它,并使用单独的更新语句执行更新。智能OR映射器只会获取主键,直到需要额外的数据,但是它们通常会获取整个其余部分,因为一次只获取一个属性会花费很多。

如果您真的关心此优化,请使用存储过程或手写SQL语句。如果您想要更加紧凑的代码,可以使用以下内容。

db.FileEntities.
    Where(x => ids.Contains(x.ID)).
    Select(x => x.DateDeleted = DateTime.Now; return x; );

db.SubmitChanges();

我不喜欢这样,因为我发现它不太可读,但有些人更喜欢这样的解决方案。

答案 1 :(得分:0)

LINQ to SQL是一个ORM,与其他任何一样,因此,它不是为处理批量更新/插入/删除而设计的。 L2S,EF,NHibernate,LLBLGen以及其他的一般思想是为您处理关系数据到对象图的映射,从而无需管理存储过程的大型库,这最终会限制您的灵活性和适应性。

当谈到批量更新时,最好留给那些最好的东西......数据库服务器。 L2S和EF都提供了将存储过程映射到模型的功能,这使得存储过程可以在某种程度上面向实体。由于您使用的是L2S,只需编写一个以身份集作为输入的proc,并在问题开头执行SQL语句。将存储的proc拖到L2S模型上,然后调用它。

它是解决手头问题的最佳解决方案,即批量更新。与报告一样,对象图和对象关系映射不是批量过程的最佳解决方案。