【问题标题】:Fetch max records of parent in one to many relationship在一对多关系中获取父级的最大记录
【发布时间】:2013-02-21 17:18:54
【问题描述】:

假设两个类有一个 ParentClass 和一个 ChildClass。父母有一个袋子要孩子。
我已经尝试过 .SetResultTransformer(new DistinctRootEntityResultTransformer()) 和 distinct() 过滤掉重复并且在获取 .SetMaxResults() 时我没有在 ParentClass 级别得到它。

有什么东西可以用来让 .SetMaxResults() 在 ParentClass 级别而不是 ChildClass 上工作。我需要在父级别强制执行 maxresults。

示例 ParentClass 有 6 个子项,setmaxresults(6) 和 distinct() 将导致我在查询中查找更多 5 个 ParentClass 记录时得到一个 ParentClass。我的标准包括 3 个与父记录匹配的参数和 2 个与子记录匹配的参数

【问题讨论】:

    标签: c# nhibernate


    【解决方案1】:

    一种解决方案是使用子查询。文档14.11. Subqueries

    它将像内部选择一样工作。子查询将包含带有 2 个参数以匹配 Child 的 WHERE 子句,以及返回 Parent.ID 的投影。然后,主查询将包含 3 个参数以过滤 Parent,并调用子查询以匹配 Parent ID

    子查询:

    var sub = DetachedCriteria
     .For<Child>()
     .Add(Restrictions.In("FirsChildProperty", new int[] {1, 2 })) // WHERE
     .Add(Restrictions.... // Second
     .SetProjection(Projections.Property("Parent.ID")); // Parent ID as a SELECT clause
    

    主查询:

    var criteria = session.CreateCriteria<Parent>()
     .Add(Restrictions.In("FirsParentProperty", new int[] {1, 2 })) // WHERE
     .Add(Restrictions.... // the second
     .Add(Restrictions.... // the third
     // no filter to match children
     .Add(Subqueries.PropertyIn("ID", sub)); // Parent.ID in (select
     // now paging just over Parent table....
     .SetFirstResult(100) // skip some rows
     .SetMaxResults(20)   // take 20
    
    var result = criteria.List<Parent>();
    

    【讨论】:

    • 感谢您的回复。我有一个小问题。就像我父母的第一列是“第一”,第二列是“第二”,第三列是“第三”,对于孩子来说,它的“第四”和“第五”。如果我使用 Restrictions,我有这 5 个输入的列表。它会遵循相同的顺序,例如 Parent 有 3,child 有 2。或者我应该使用循环来添加限制。
    • 不确定我是否理解 ;) 但是。子查询sub 正在处理一个孩子。因此,您可以在其属性上应用任何过滤器(In、equal、Like)。然后,当使用父 criteria 时,任何限制都可以转到父属性(名字等于...年龄大于...)然后结果将过滤父并仅采用符合子查询结果的父 ID 跨度>
    • 确实给出了一些记录,但“Param1”、“Param2”、“Param3”、“Param4”、“Param5”必须严格匹配父母 param1,param2,param3 和子 param4,param5。不严格匹配。
    • 我向您展示的解决方案非常灵活。但必须有一些其他的逻辑到位。因此,您将创建 Subquery 并根据条件添加限制(稍后的 WHERE 子句元素)。您将使用这个地方来限制子属性的父级。与Criteria query 相同,可以调整为Parent 上的任何过滤器。使用 if, switch... 只需根据需要使用 criteriasub。最后将它们放在一起并调用 .List()...
    • 我们有什么东西可以在父级强制执行 setmaxrecords。目前在构建记录集时它处于子级别。并且当产生不同时,记录集再次被修剪。
    猜你喜欢
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多