C# 对字符串集合进行QueryOver筛选:NullReferenceException

C# 对字符串集合进行QueryOver筛选:NullReferenceException,c#,nhibernate,queryover,C#,Nhibernate,Queryover,我有很多东西。每个项目都属于一个组。每个项目都有一个可能为空的标签字符串列表,这些标签字符串有助于增强文本搜索。搜索应查找与其描述、所属组的描述或一个或多个标记匹配的项目,所有这些都在或条件中 我正试图通过以下查询通过搜索键选择项目 Item i = null; ItemGroup g = null; String tag = null; session .QueryOver<Item>(() => i) .JoinAlias(x => x.Group,

我有很多东西。每个项目都属于一个组。每个项目都有一个可能为空的标签字符串列表,这些标签字符串有助于增强文本搜索。搜索应查找与其描述、所属组的描述或一个或多个标记匹配的项目,所有这些都在或条件中

我正试图通过以下查询通过搜索键选择项目

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。删除析取中的最后一个条件时,不会引发异常


我没有使用魔法弦就无法摆脱它。

使用这个,如果我误解了,请纠正我

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();

我最近没有检查过,但据我所知,NHibernate不支持直接使用QueryOver或Criteria API查询值集合

我建议您最好的解决方法是使用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();

.AddRestrictions.On=>tag.IsInsensitiveLikesearchKey,MatchMode。此行上的开始标记应为tag.tag,因为您已将Tags表的别名定义为tag,但Searchtag中未提及的字段是纯字符串对象。它没有标记属性。实际上,标记是一个字符串。它没有标记属性。您已将标记引用为标记,您应该使用Tags.Tag属性来搜索它。你试过密码吗?我试过你的密码。它不编译。标记只是一个普通的字符串对象。我还尝试用=>I.Tags替换我的=>tag。在最后一种情况下,根本不会触发对DB的查询,并且会毫无例外地返回一个空结果集。对不起,如果我不理解你的建议。尽量说得更准确些。谢谢。我不知道为什么,但只要我向析取添加一个标准,查询就不会执行,没有例外。即使SqlCriteriam的定义如下,也会发生这种情况:新的SqlCriterianNewSqlString{alias}.Id=?,新的[]{searchKey+%},新的[]{NHibernateUtil.String}@Marcello而不是new SqlString请尝试SqlString.Parse。@Marcello new SqlString在搜索参数时不分析字符串,SqlString.Parse会。