NHibernate有没有办法让这个查询更容易?
为了理解,这是我想用NHibernate创建的查询:
Select * from Task Where task_id not in (Select task_id from UserTask Where solved = 1 AND [user_id] = 1)
这个是我在NH#中的C#代码
public IList<Task> RandomTasks(List<int> subject_ids,int userId) { //Gets all Ids where the User has solved the Task List<int> task_ids = new List<int>(_session.Query<UserTask>() .Where(x => x.User.user_id == userId) .Where(x => x.solved) .Select(x => x.Task.task_id)); //Gets all Tasks except the task_ids from the result of the query befor var query = _session.QueryOver<Task>() .Where(s => s.Subject.subject_id.IsIn(subject_ids)) .Where(t => !t.task_id.IsIn(task_ids)) .Take(10) .List(); return query; }
解决方法
如果您更喜欢INNER SELECT,NHiberante确实为您提供了解决方案.它被称为DetachedCriteria. (尝试检查
here的类似示例)
首先我们将创建内部选择:
var sub = DetachedCriteria .For<UserTask>() // WHERE .Add(Restrictions.In("UserId",new int[] { 1,2 })) // example of filtering 'user_id' .Add(Restrictions.Eq("solved",true)) // 'solved' .SetProjection(Projections.Property("TaskId")); // TaskId the SELECT clause
(我不确定你的模型和命名,例如task_id vs TaskId …但意图应该清楚)
使用DetachedCritera我们可以做很多事情,我们可以加入其他引用的对象/表,过滤它们……就像标准的QueryOver一样.唯一的区别是,我们应该返回Projection(SELECT TaskId)作为另一个查询中的过滤器:
var criteria = session.CreateCriteria<Task>(); criteria . Where(... // your filters applied on Task .Add(Subqueries.PropertyIn("ID",sub)); // Task.ID in (select...
var result = criteria.List();
NOTE. This solution will not only work ;),but mostly,it is ready for
paging and sorting. So even in cases,that the inner select will return more ‘similar’ results (same ids),the upper select will return each task only once…
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。