如果只更改了一列,LINQ是否会在db中更新整个对象?

时间:2014-01-13 15:22:58

标签: c# sql-server linq entity-framework

如果一个对象有多个列且程序只更新一列,LINQ是否会更新数据库中的所有列,无论它们是否被更改,或者它只更新了更改的列?

示例类:

MyObject
{
    int ID {get; set}
    string Field1 {get; set}
    string Field2 {get; set}
    string Field3 {get; set}
    string Field4 {get; set}
    string Field5 {get; set}
}

现在,我从数据库中获取一个recod并仅更改一个字段

var myObject= 
(
   from x in db.TableName
   where x.ID == 12345
   select x
)
.Single();

myObject.Field1 = "something";

db.SubmitChanges();

SQL查询是对所有列还是仅对Field1列执行更新语句?

1 个答案:

答案 0 :(得分:1)

不是那么精细。 (也不应该这样,因为列级跟踪会在并发跟踪中引入一大堆复杂性,这已经是一个困难且折衷主义的主题。)

当您使用ORM(例如Linq to SQL,Entity Framework等)时,重点是对象。框架将该对象(实际上是相关对象的整个图)映射到关系数据库模式中。但是,当您将更改提交到ORM以进行持久性时,您要更新的是对象图。

ORM将跟踪哪些对象发生了变化,并将根据所提出的映射逻辑和并发规则在对象级别进行并发检查。但是它将为每个记录编译SQL更新语句,因为它对应于对象。

对象的状态发生了变化,因此它应该保持在全新的状态。虽然在列级别跟踪更改肯定是可能,但这种投资的回报并不存在。代码将非常更复杂,这意味着:

  • 支持
  • 会困难得多
  • 它会更容易出错
  • 运行得慢得多
  • 理解和预测其行为要困难得多
  • 当然,更不用说并发跟踪中的许多新的混乱。 (假设用户A更新了记录X的电话号码,用户B同时更新记录X的地址。您如何建议自动合并这些更改?我相信您可以想象那里有更多,更复杂的例子。)

在这种情况下,权衡不会加起来。使用ORM时,您正在更新对象。持久性模型是抽象的(并且无论如何都进行了很好的优化)。

对于交易系统,这是理想的。在为事务系统提交工作单元时,在绝大多数情况下,您将从聚合根(或少量聚合根)开始,并更新它们下面的对象图。关系图是这个场景中更重要的部分,这就是ORM要处理的内容。

为了对目标列进行批量更新,您不再谈论事务系统中的工作单元。此时,您正在谈论直接与表数据交互以进行数据操作,数据迁移,甚至是一些商业智能任务。这是一个完全不同的工具集,超出了ORM提供的范围。