1

アイテムがあります。各アイテムはグループに属しています。また、各アイテムは、テキスト検索を強化するのに役立つタグ(文字列)の(おそらく空の)リストを所有しています。検索では、説明、所属するグループの説明、または1つ以上のタグ(すべてOR条件)に一致するアイテムが見つかります。

次のQueryOverを使用して、検索キーでアイテムを選択しようとしています。

Item i = null;
ItemGroup g = null;
String tag = null;

session
    .QueryOver<Item>(() => i)
    .JoinAlias(x => x.Group, () => g, JoinType.InnerJoin)
    .JoinAlias(x => x.Tags, () => tag, JoinType.LeftOuterJoin) //left outher join because it is possible for an item to have no tags at all.
    .Where(
        new Disjunction()
            .Add(Restrictions.On(() => p.Description).IsInsensitiveLike(searchKey, MatchMode.Anywhere))
            .Add(Restrictions.On(() => g.Description).IsInsensitiveLike(searchKey, MatchMode.Start))
            .Add(Restrictions.On(() => tag).IsInsensitiveLike(searchKey, MatchMode.Start)) //this condition throws an exception
    )
    .Take(maxResults)
    .Future();

アイテムクラスは次のようにマップされます。

<class name="Item" table="Items">
<id name="Id">
    <generator class="guid.comb" />
</id>

    <natural-id>
        <property name="Code" not-null="true" />
    </natural-id>
    <property name="Description" not-null="true" />
    <many-to-one name="Group" column="ID_Group" not-null="true" fetch="join" />
    <property name="ExpiryDate" />
    <list name="Tags" table="Items_Tags">
        <key column="ID_Item" />
        <index column="Idx" />
        <element column="Tag" />
    </list>
</class>

クエリを実行すると、NullReferenceExceptionがスローされます。論理和の最後の条件を削除しても、例外はスローされません。

私はマジックストリングを使わずにこれを取り除くことはできませんでした。

4

2 に答える 2

1

これを使って、誤解したら訂正してください

session
    .QueryOver<Item>(() => i)
    .JoinAlias(x => x.Group, () => g, JoinType.InnerJoin)
    .JoinAlias(x => x.Tags, () => tag, JoinType.LeftOuterJoin) //left outher join because it is possible for an item to have no tags at all.
    .Where(
        new Disjunction()
            .Add(Restrictions.On(() => p.Description).IsInsensitiveLike(searchKey, MatchMode.Anywhere))
            .Add(Restrictions.On(() => g.Description).IsInsensitiveLike(searchKey, MatchMode.Start))
            .Add(Restrictions.On(() => tag.Tag).IsInsensitiveLike(searchKey, MatchMode.Start)) //this condition throws an exception
    )
    .Take(maxResults)
    .Future();
于 2012-08-31T07:34:47.383 に答える
1

最近チェックしていませんが、私が知る限り、NHibernateはQueryOverまたはCriteriaAPIを直接使用した値のコレクションに対するクエリをサポートしていません。

最善の回避策は、SQLCriteriaを使用することです。

        var tagCriteria = new SQLCriterion(
            new SqlString("{alias}.Id IN (SELECT ID_Item FROM Items_Tags WHERE Tag LIKE ?)"),
            new[] {searchKey + "%"},
            new[] {NHibernateUtil.String}
            );

        session
            .QueryOver<Item>(() => i)
            .JoinAlias(x => x.Group, () => g, JoinType.InnerJoin)
            .Where(
                new Disjunction()
                    .Add(Restrictions.On(() => p.Description).IsInsensitiveLike(searchKey, MatchMode.Anywhere))
                    .Add(Restrictions.On(() => g.Description).IsInsensitiveLike(searchKey, MatchMode.Start))
                    .Add(tagCriteria)
            )
            .Take(maxResults)
            .Future();
于 2012-08-31T15:40:21.297 に答える