【问题标题】:NHibernate efficient Delete using LINQ Where conditionNHibernate 高效删除使用 LINQ Where 条件
【发布时间】:2017-11-01 19:50:40
【问题描述】:

拥有一个 NHibernate 存储库,带有这样的 LINQ 查询

var q = from x in SomeIQueryable<SomeEntity> where x.A1 == a1 && x.B1 == b1 select x;

是否有解决方案如何获取此 WHERE 过滤器并将其应用于“一次性删除”,这似乎只能通过 HQL 实现:

var cmd = string.Format("delete from SomeEntity where x.A1 = '{0}' and x.B1 = {1}", a1, b1);
session.CreateQuery(cmd).ExecuteUpdate();

【问题讨论】:

    标签: c# linq nhibernate


    【解决方案1】:

    现在可以使用 Nhibernate 5.0:

    session.Query<SomeIQueryable>()
                .Where(x => x.A1 == a1 && x.B1 == b1)
                .Delete();
    

    文档:

        //
        // Summary:
        //     Delete all entities selected by the specified query. The delete operation is
        //     performed in the database without reading the entities out of it.
        //
        // Parameters:
        //   source:
        //     The query matching the entities to delete.
        //
        // Type parameters:
        //   TSource:
        //     The type of the elements of source.
        //
        // Returns:
        //     The number of deleted entities.
        public static int Delete<TSource>(this IQueryable<TSource> source);
    

    【讨论】:

    • 这样做的问题是,如果存在被删除实体的映射子项,例如包(一对多),它似乎会失败。我得到一个 FK 约束违规,因为孩子们对他们的父母有一个 FK,实体被删除。要获得级联删除,我必须先加载实体,然后使用session.Delete(entity)
    • @E-Riz 你可以尝试用你的子集合“反转”你的映射来改变这个行为stackoverflow.com/questions/713637/…
    【解决方案2】:

    NH LINQ 提供程序和条件/queryover API 不支持条件删除/更新。除非您正在考虑扩展 NHibernate,否则 HQL 或原始 SQL 是唯一的选择。

    【讨论】:

    • 那在回答的时候是对的,但是现在有一种使用 Linq to Sql 的方法。见下文
    【解决方案3】:
    (from x in NHSession.Query<SomeEntity>()
                      where x.A1 == a1 && x.B1 == b1 
                      select x).ForEach(y => { NHSession.Delete(y) });
            NHSession.Flush();
    

    【讨论】:

    • 请发表一些解释;纯代码回答不多说。
    • 这样做的问题是它加载所有实体只是为了删除它们。
    • 这不是我们所说的高效
    • 题主问怎么做“one-shot-delete”,你的解决方案会为每个符合条件的“SomeEntity”实例执行一个DELETE语句
    【解决方案4】:

    目前,从 NH 4.0.1 开始,这是不可能的。然而,Jira 有一个未解决的问题(NH-3659,https://nhibernate.jira.com/browse/NH-3659)。有一个基于http://weblogs.asp.net/ricardoperes/strongly-typed-delete-with-nhibernate 中描述的自定义拦截器和 SQL 替换的黑客解决方案,但我正在研究一个干净的解决方案,最终将提交一个拉取请求。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-18
    • 2018-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多