C# 如果只更改了一列,LINQ会更新数据库中的整个对象吗?

C# 如果只更改了一列,LINQ会更新数据库中的整个对象吗?,c#,sql-server,linq,entity-framework,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} } 现在,

如果一个对象有多个列,而程序只更新一列,那么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查询是在所有列上执行update语句,还是只在Field1列上执行update语句?

它没有那么精细。(也不应该这样,因为列级跟踪会给并发跟踪带来大量复杂性,而并发跟踪已经是一个困难且充满妥协的主题。)

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

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

对象的状态是更改的,因此它应该保持在其全新的状态。虽然当然可以在列级别跟踪变化,但这方面的投资回报并不存在。代码要复杂得多,这意味着:

  • 这将更加难以支持
  • 它更容易出错
  • 它将运行得慢得多
  • 要理解和预测它的行为要困难得多
  • 当然,更不用说并发跟踪中出现了许多新的混乱。(假设用户A更新了记录X的电话号码,而用户B同时更新了记录X的地址。您将如何建议自动合并这些更改?我相信您可以从中想象出更多、更复杂的示例。)
在这种情况下,这种权衡是不合算的。使用ORM时,您正在更新对象。持久性模型是抽象的(并且已经很好地优化了)

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


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

我认为编译的update语句适用于所有列。(你可以通过分析数据库交互来确定答案,但我99%确定它都是列。)这有区别吗?如果是这样的话,我怀疑设计中还存在其他错误……这实际上是一个更具理论性的问题?如果一个表中有300列,而我只需要更新一列,该怎么办?单个表中的300列对我来说意味着存在数据库设计问题。300列对于数据仓库之类的东西可能有意义,但您通常不会像事务数据库那样使用ORM与数据仓库交互。关键是,ORM正在更新对象,就像它的整体一样。当然可以使其更细粒度,但我怀疑投资回报率很可能为负值。请告诉我,如果更新1列或500列,性能下降的地方。@ebyrob我不相信EF在更新时会向数据库发送delete和insert语句。但当您进行更新时,SQLServer会在内部删除和插入。