【问题标题】:Does LINQ update whole object in db if only one column is changed?如果仅更改一列,LINQ 是否会更新 db 中的整个对象?
【发布时间】:2014-01-13 23:51:40
【问题描述】:

如果一个对象有多个列并且程序只更新一列,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}
}

现在,我从 db 中获取一个记录并只更改一个字段

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

myObject.Field1 = "something";

db.SubmitChanges();

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

【问题讨论】:

  • 我想编译的更新语句适用于所有列。 (您可以分析数据库交互以确定确定,但我 99% 确定它是所有列。)这有什么不同吗?如果是这样,我怀疑设计中还有其他问题......
  • 这实际上是一个更理论的问题?如果一个表中有 300 列,而我只需要更新一个怎么办?
  • 单个表中的 300 列对我来说意味着存在数据库设计问题。 300 列对于数据仓库之类的东西可能有意义,但您通常不会像使用事务数据库那样使用 ORM 与数据仓库进行交互。关键是,ORM 正在按原样和整体更新对象。当然可以让它比这更细化,但我怀疑投资回报率是负数。
  • 如果您更新 1 或 500 列,请告诉我性能下降的地方。
  • @ebyrob 我不相信 EF 在更新时会向数据库发送删除和插入语句。但是当您进行更新时,SQL Server 会在内部进行删除和插入。

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


【解决方案1】:

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

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

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

object 的状态发生了变化,因此它应该以全新的状态持续存在。虽然可能在列级别跟踪更改,但投资回报并不存在。代码会大大更复杂,这意味着:

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

在这种情况下,权衡只是没有加起来。使用 ORM 时,您正在更新一个对象。持久性模型是抽象的(无论如何优化得很好)。

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

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

【讨论】:

    猜你喜欢
    • 2019-06-02
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多