【问题标题】:Nhibernate - Update single field without loading entity?Nhibernate - 在不加载实体的情况下更新单个字段?
【发布时间】:2019-07-08 22:16:52
【问题描述】:

我有一个用例,用户获取产品列表,并且可以选择多个产品并激活或停用它们。

此列表的模型是不可变的,并且我有一个存储库,其中包含应该将它们全部停用的模型列表。

我确实有另一个完整的产品编辑模型,但我宁愿不必加载数百个模型来简单地更改一列。

我正在考虑使用 Session.CreateQuery,但有没有更好的方法来完成这个?

【问题讨论】:

    标签: c# nhibernate


    【解决方案1】:

    HQL 是要走的路。

    Session.CreateQuery("update Product set Active = :active where id in (:ids)")
           .SetParameter("active", active)
           .SetParameterList("ids", listOfSelectedProductIds)
           .ExecuteUpdate();
    

    【讨论】:

    • 没有HQL有办法吗?我想使用已经存在的映射而不是编写内联查询,这首先是 ORM 背后的想法。
    • ORM 的主要目的之一是避免编写查询。您的解决方案将所有反模式组合在一个包中:1)内联 DB 语句; 2)使用一个巨大的抽象层——NH——本质上调用一个简单的SQL语句——没有充分的理由并且成本很高; 3) 不使用数据模型映射。 (请不要冒犯)
    • @mr.ta,你大错特错了。 HQL 不是 DB 语句,它是 ORM 的一部分,它使用映射(您指的是类和属性,而不是表)。无意冒犯,但请阅读 NH 文档。
    • 你没有抓住重点。它使用映射来执行本质上是美化的字符串替换操作这一事实使它变得更糟,而不是更好。是的,它使用映射,这意味着抽象层的所有开销,但它仍然让您编写内联查询(即使它是“HQL”),这意味着内联查询的所有不可靠性和不可维护性。
    • 适合自己。再说一次,我不是来找你的,你的答案是一个有效的答案——即使我认为这是一个糟糕的方法。
    【解决方案2】:

    从 NHibernate 5 开始,您可以使用 LINQ 进行更新/删除,如下所示:

    session.Query<Product>()
        .Where(p => listOfSelectedProductIds.Contains(p.Id))
        .Update(p => new { Active = active });
    

    它不会加载实体或增加版本。

    https://nhibernate.info/doc/nhibernate-reference/querylinq.html#querylinq-modifying

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多