我有物品。每个项目属于一个组。每个项目都拥有一个(可能是空的)标签(字符串)列表,可用于增强文本搜索。搜索应该找到与其描述相符的项目,它们所属的组的描述或一个或多个标签(全部在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();
Item类映射如下:
<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。删除析取中的最后一个条件不会抛出异常。
如果不使用魔法琴弦,我没有摆脱这种情况。
答案 0 :(得分: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();
答案 1 :(得分:1)
我最近没有检查过,但据我所知,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();