C# 使用nHibernate按子集合限制查询权限

C# 使用nHibernate按子集合限制查询权限,c#,nhibernate,C#,Nhibernate,我试图获取一个父实体,其中子集合中的所有实体都位于另一个列表中 例如: public class Parent { public virtual int Id {get;set;} public virtual List<Child> Children {get;set;} } public class Child { public virtual int Id {get;set;} public virtual string Name {get;set;} } 以下是我

我试图获取一个父实体,其中子集合中的所有实体都位于另一个列表中

例如:

public class Parent {

public virtual int Id {get;set;}
public virtual List<Child> Children {get;set;}

}

public class Child {

public virtual int Id {get;set;}
public virtual string Name {get;set;}

}
以下是我的建议:

var parents = session.QueryOver<Child>()
  .WhereRestrictionOn(x => x.Name).IsIn(names)
  .Select(Projections.Group<Child>(x => x.Parent))
  .Where(Restrictions.Ge(Projections.Count<Child>(x => x.Parent), names.Length))
  .List<Parent>();
我已经创建了一个测试应用程序,返回了有希望的结果

如果您需要对父项执行更多操作,如分页或获取子项,则可以将此问题拆分为子查询(请注意,
.Fetch(x=>x.children)。不需要使用Eager
行,这只是一个示例,您可以进一步处理查询):

更新:

如果ParentChild是多对多,事情会变得有点棘手:

      Parent parent = null;
      var parentSubQuery = QueryOver.Of<Child>()
        .WhereRestrictionOn(x => x.Name).IsIn(names)
        .JoinQueryOver(x => x.Parents, () => parent)
        .Where(Restrictions.Ge(Projections.Count(() => parent.Id), names.Length))
        .Select(Projections.Group(() => parent.Id));

      var parents = session.QueryOver<Parent>()
        .WithSubquery.WhereProperty(x => x.Id).In(parentSubQuery)
        .List();

对于我的测试场景,它是有效的,所以希望它也能对您起作用。

为了清楚起见,子项应该匹配列表中的每个项。您希望所有父项都有确切的名称吗?长度子项,其中每个项都有一个子项的名称(以该项为名称)?不,他们可以有更多,因此父项可以有10个子项,但只需要匹配名称列表中的3个。(例如)这很好,这意味着我可能会有一个答案(见下面的答案)这是同一个问题吗?哦,这太棒了,唯一会稍微影响你的问题是一个孩子可以有很多父母,而不仅仅是一个。所以“.Select(Projections.Group(x=>x.Parent.Id))不会编译吗?谢谢对不起,我已经上床睡觉了。父母子女是多对多的,这使得在新罕布什尔州做这件事更加困难。我需要测试一下。请继续关注:-)另一个更新,这一次的解决方案非常接近我对多对一场景的初始方法。非常感谢,是的,这是多对多,我想人类需要一本关于nhibernate的书!
var parents = session.QueryOver<Child>()
  .WhereRestrictionOn(x => x.Name).IsIn(names)
  .Select(Projections.Group<Child>(x => x.Parent))
  .Where(Restrictions.Ge(Projections.Count<Child>(x => x.Parent), names.Length))
  .List<Parent>();
SELECT
    this_.Parent as y0_
FROM
    Child this_
WHERE
    this_.Name in (
        /*  */
    )
GROUP BY
    this_.Parent
HAVING
    count(this_.Parent) >= /* names.Length */;
var parentSubQuery =
  QueryOver.Of<Child>()
    .WhereRestrictionOn(x => x.Name).IsIn(names)
    .Select(Projections.Group<Child>(x => x.Parent))
    .Where(Restrictions.Ge(Projections.Count<Child>(x => x.Parent), names.Length));

var parents = session.QueryOver<Parent>() 
  .Fetch(x=>x.Children).Eager // not necessary, just an example
  .WithSubquery.WhereProperty(x => x.Id).In(parentSubQuery )
  .List();
SELECT
    this_.Id as Id1_0_
FROM
    Parent this_
WHERE
    this_.Id in (
        SELECT
            this_0_.Parent as y0_
        FROM
            Child this_0_
        WHERE
            this_0_.Name in (
                /* names */
            )
        GROUP BY
            this_0_.Parent
        HAVING
            count(this_0_.Parent) >= /* names.length */
    );
      Parent parent = null;
      var parentSubQuery = QueryOver.Of<Child>()
        .WhereRestrictionOn(x => x.Name).IsIn(names)
        .JoinQueryOver(x => x.Parents, () => parent)
        .Where(Restrictions.Ge(Projections.Count(() => parent.Id), names.Length))
        .Select(Projections.Group(() => parent.Id));

      var parents = session.QueryOver<Parent>()
        .WithSubquery.WhereProperty(x => x.Id).In(parentSubQuery)
        .List();
SELECT
    this_.Id as Id2_0_
FROM
    Parent this_
WHERE
    this_.Id in (
        SELECT
            parent1_.Id as y0_
        FROM
            Child this_0_
        inner join
            ChildToParent parents3_
                on this_0_.Id=parents3_.ChildId
        inner join
            Parent parent1_
                on parents3_.ParentId=parent1_.Id
        WHERE
            this_0_.Name in (
                /* names */
            )
        GROUP BY
            parent1_.Id
        HAVING
            count(parent1_.Id) >= /* names.Length */
    );