[英]How to do an NHibernate QueryOver with “not in”?
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
。 (試着在這里查看類似的例子)
首先我們將創建內部選擇:
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();
注意。 這個解決方案不僅可以工作;),但大多數情況下,它已准備好進行分頁和排序 。 因此,即使在情況下,內部選擇將返回更多“相似”結果(相同的ID),上部選擇將僅返回每個任務一次...
您可以使用left join
:
Select t.* from Task t
left join UserTask ut on t.Id = ut.TaskId
and ut.UserId = 1 and ut.solved = 1
where ut.id is null
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.