我如何查询 returns 个包含列表中所有 ID 的对象

How can I make a query that returns objects who contain all ids from list

我有两个对象:配置文件和标签。每个配置文件可以包含多个标签。在我的搜索页面上,我可以 select 多个标签进行搜索。现在我想要一个查询来获取所有具有所有 selected 标签的配置文件。

因此,如果我使用 WhereRestrictionOn().IsIn(),我会得到至少包含 1 个标签的配置文件,但我需要 return 包含列表中所有标签的配置文件。

我还为每个 selected 标签尝试了多个 Where 条件,但后来我根本没有得到任何结果。

我不知道该怎么做,非常感谢任何帮助!

Structure:

Profile : Id

ProfileTag : ProfileId, TagId

Tag: Id

映射配置文件

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Agrolink.Application.Models" assembly="Agrolink.Application">
  <class name="Agrolink.Application.Models.Profile" lazy="false" table="Profiles" >

    <id name="Id" column="Id"  >
      <generator class="identity" />
    </id>

    <bag name="Tags" table="ProfileTags" cascade="all-delete-orphan" inverse="true">
      <key column="IdProfile" not-null="true"/>
      <one-to-many class="Agrolink.Application.Models.ProfileTag"  />
    </bag>

  </class>
</hibernate-mapping>

映射配置文件标签

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Agrolink.Application.Models" assembly="Agrolink.Application">
  <class name="Agrolink.Application.Models.ProfileTag" lazy="false" table="ProfileTags" >

    <id name="Id" column="Id"  >
      <generator class="identity" />
    </id>

    <many-to-one name="Profile" class="Agrolink.Application.Models.Profile" column="IdProfile" cascade="save-update" />
    <many-to-one name="Tag" class="Agrolink.Application.Models.Tag" column="IdTag" cascade="none" />

  </class>
</hibernate-mapping>

映射标签

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Agrolink.Application.Models" assembly="Agrolink.Application">
  <class name="Agrolink.Application.Models.Tag" lazy="false" table="Tags" >

    <id name="Id" column="Id"  >
      <generator class="identity" />
    </id>

    <property name="Name" column="Name" />
    <property name="Type"  type="Agrolink.Application.Models.TagType, Agrolink.Application"  column="IdType" />

    <many-to-one name="Parent" class="Agrolink.Application.Models.Tag" column="IdParent" cascade="none" />

    <bag name="Children" table="Tags" cascade="all" inverse="true">
      <key column="IdParent" not-null="true"/>
      <one-to-many class="Agrolink.Application.Models.Tag"  />
    </bag>

  </class>
</hibernate-mapping>

子查询实现(解决):

        Profile p = null;
        Account a = null;
        Institute i = null;

        var q = Session.QueryOver(() => p)
            .JoinAlias(x => x.Account, () => a)
            .JoinAlias(x => x.Institute, () => i)
            .Where(x => x.Type == ProfileType.Expert && x.Status == ProfileStatus.Active);

        if(_keywordIds.Any())
            foreach (var keywordId in _keywordIds)
            {
                Tag t = null;

                var subQ = QueryOver.Of<ProfileTag>()
                    .JoinAlias(pt => pt.Tag, () => t)
                    .Where(() => t.Id == keywordId)
                    .Select(pt => pt.Profile.Id);           

                q.WithSubquery.WhereProperty(() => p.Id).In(subQ);
            }

        if (_institute != null) q.Where(() => i.Id == _institute);

        if (!string.IsNullOrEmpty(_name)) q.Where(Restrictions.Disjunction()
                    .Add(Restrictions.Like("a.FirstName", _name + "%"))
                    .Add(Restrictions.Like("a.LastName", _name + "%"))
                );

        return (PagedList<Profile>) q.List<Profile>().ToPagedList(_page, _itemsPerPage);

差不多了,但是我们需要所谓的 Detached QueryOver,我们将通过构造获得它 QueryOver.Of

foreach (var keywordId in _keywordIds)
{
    //Tag t = null;

    var subQ = QueryOver.Of<ProfileTag>()
        //.JoinAlias(pt => pt.Tag, () => t)
        //.Where(() => t.Id == keywordId)
        .Where(x => x.Tag.Id == keywordId)
        //.Select(pt => t.Id);           
        .Select(pt => pt.Profile.Id);          

    q.WithSubquery.WhereProperty(() => p.Id).In(subQ);
}