如何解决如何在NHibernate 3中实现搜索查询使用NHibernate.Linq
| 我正在尝试使用NHibernate建立一个搜索查询,该查询将对来自几个不同表的参数进行过滤,并产生可以利用NHibernate的延迟加载的合理的SQL。 从网上阅读各种技巧,似乎最新和最好的方法是使用QueryOver对象有条件地添加正在使用的参数,如以下代码片段所示:Hibernate.Criterion.QueryOver<Models.Site,Models.Site> query = NHibernate.Criterion.QueryOver.Of<Models.Site>();
if (!string.IsNullOrEmpty(state))
query = query.WhereRestrictionOn(r => r.State.StateName).IsInsensitiveLike(\"%\" + state + \"%\");
if (startDate.HasValue)
query = query.Where(r => r.Events
.Where(e=>e.EventDate >= startDate.Value)
.Count() > 0
);
return query.GetExecutableQueryOver(currentSession).Cacheable().List();
(事件具有外键)
我有两个问题:
如何过滤子对象,而不只是父对象?上面的示例代码为我提供了所有具有匹配事件的站点,但是在该站点内,我只希望具有匹配事件。如果我应该使用联接或子查询,该怎么办?我对通过联接或子查询进行延迟加载来维护树状层次结构感到困惑。
编辑:这已经回答。谢谢psousa!
如何添加or子句?我找到了对Disjunction对象的引用,但是使用QueryOver方法似乎不可用。
编辑:
我想得到按站点条件过滤的站点列表(顶级对象),并且每个站点都应具有按事件条件过滤的事件列表。
我希望它会生成如下所示的SQL:
SELECT *
FROM [site] s
LEFT JOIN [event] e ON s.siteID = e.siteID
WHERE e.eventDate > @eventDate
AND (s.stateCd = @state OR s.stateName LIKE @state)
解决方法
我会这样查询:
//use aliases. Optional but more practical IMHO
Site siteAlias = null;
Event eventAlias = null;
//use JoinAlias instead of JoinQueryOver to keep the condition at the \"Site\" level
var results = Session.QueryOver(() => siteAlias)
.JoinAlias(m => m.Event,() => eventAlias)
.Where(() => eventAlias.EventDate > eventDate)
.Where(() => siteAlias.StateCd == state || Restrictions.On(() => siteAlias.StateName).IsLike(state))
.List();
您提到了Disjunction类,它实际上可以与QueryOver一起使用,例如:
var disjunction= new Disjunction();
disjunction.Add(() => siteAlias.StateCD == state);
disjunction.Add(Restrictions.On(() => siteAlias.StateName).IsLike(state));
QueryOver查询将是:
var results = Session.QueryOver(() => siteAlias)
.JoinAlias(m => m.Event,() => eventAlias)
.Where(() => eventAlias.EventDate > eventDate)
.Where(disjunction)
.List();
, 当按照psousa的建议使用连接别名时,您将得到对象结构和行结构的奇怪组合,结果是顶级对象被附加到它们的子对象复制。为了获得我一直在寻找的结果,可以使用TransformUsing和DistinctRootEntityResultTransformer,如以下代码所示:
Site siteAlias = null;
Event eventAlias = null;
var results = currentSession.QueryOver<Site>(() => siteAlias)
.JoinAlias(m => m.Event,() => eventAlias)
.Where(() => eventAlias.EventDate > eventDate)
.Where(() => siteAlias.StateCd == state || Restrictions.On(() => siteAlias.StateName).IsLike(state))
.TransformUsing(new NHibernate.Transform.DistinctRootEntityResultTransformer())
.List();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。