2013-11-01 58 views
2

我試圖重新NHibernate的以下查詢:SQL查詢NHibernate的與具有COUNT

SELECT DISTINCT 
     orderid , 
     tasktype 
FROM "Task" 
WHERE orderid IN (SELECT orderid 
        FROM "Task" 
        GROUP BY orderid 
        HAVING COUNT(orderid) > 1) 
ORDER BY orderid 

在NH,我需要返回基於訂單id任務類型列表的QueryOver。基本上,我遍歷每個任務以及對於每次發生多次的任務(由於不同的任務類型),我需要將所有這些任務添加到返回給客戶端的列表中。這是我迄今爲止與NH一起嘗試過的。

var taskList = new List<Task>(); 
PendingTasks = session.QueryOver<Model.Task>() 
       .WhereRestrictionOn(c => c.OrderId).IsIn(taskList) 
       .SelectList 
       (list => list 
       .SelectGroup(b => b.OrderId) 
       .Select(b => b.TaskType) 
      ) 
       .Where(Restrictions.Eq(Projections.Count<Model.Task>(x => x.OrderId), taskList.Count() > 1)) 
       .TransformUsing((Transformers.AliasToBean<TaskType>())) 
       .List<TaskType>() 

我剛剛開始NH,並在這裏找到了關於使用分組和有的一些例子。從我返回給客戶端的模型的屬性在這裏與TaskType是一個簡單的枚舉。

public List<TaskType> PendingTasks { get; set; } 

在我看來,到目前爲止,該QueryOver試圖返回一個IList,對列表的我的目標類型,但是沒有.ToList(),所以我不知道這是什麼會回來。任何與上面的sql查詢匹配的幫助是有幫助的。

UPDATE:整個方法:

private static readonly string[] TaskTypeKeys = Enum.GetNames(typeof(TaskType)); 

var tasksByType = new List<TaskGroup>(); 
       Task taskObject = null; 
       QueryOver subQuery = QueryOver.Of<Task>() 
          .Select(
          Projections.GroupProperty(
           Projections.Property<Task>(t => t.OrderId) 
          ) 
          ) 
          .Where(Restrictions.Gt(Projections.Count<Task>(t => t.OrderId), 1)); 

       foreach (var type in TaskTypeKeys) 
       { 
        TaskType typeEnum; 
        Enum.TryParse(type, out typeEnum); 

        var tasks = session.QueryOver<Model.Task>() 
         .Where(
          task => 
          task.TaskType == typeEnum && 
          task.Completed == false && 
          task.DueDate <= DateTime.Today 
         ) 
         .OrderBy(t => t.DueDate).Asc 
         .List<Model.Task>() 
         .Select(t => new Task() 
          { 
           Id = t.Id, 
           OrderId = t.OrderId, 
           CustomerId = t.CustomerId, 
           CustomerName = t.CustomerName, 
           GroupName = t.GroupName, 
           TripDate = t.TripDate, 
           TaskType = TaskTypeTitles[t.TaskType.ToString()], 
           DueDate = t.DueDate, 
           Completed = t.Completed, 
           IsActiveTask = t.IsActiveTask, 

           PendingTasks = session.QueryOver<Task>(() => taskObject) 
                     // the WHERE clause: OrderId IN (subquery) 
            .WithSubquery 
            .WhereProperty(() => taskObject.OrderId) 
        ERROR-------> .In(subQuery) 

            // the rest of your SELECT/projections and transformation 
            .SelectList(list => list 
             .SelectGroup(b => b.OrderId) 
             .Select(b => b.TaskType) 
            ) 
            .TransformUsing((Transformers.AliasToBean<TaskType>())) 
            .List<TaskType>() 
          } 
         ).ToList(); 

        tasksByType.Add(new TaskGroup() 
         { 
          Title = TaskTypeTitles[type.ToString()], 
          Content = tasks, 
          RemainingCount = tasks.Count(), 
          OverdueCount = 
           tasks.Count(
            task => 
            task.DueDate < DateTime.Today), 
         }); 
       }; 

       return tasksByType; 

的類型參數方法 'NHibernate.Criterion.Lambda.QueryOverSubqueryPropertyBuilderBase,Api.Task,Api.Task>。在(NHibernate.Criterion.QueryOve R)'不能從使用中推斷出來。嘗試明確指定類型參數。

回答

3

在這種情況下,子查詢語法將幫助我們。首先,讓我們來聲明內選擇這種方式:

QueryOver<Task> subQuery = QueryOver.Of<Task>() 
    .Select(
     Projections.GroupProperty(
      Projections.Property<Task>(t => t.OrderId) 
     ) 
    ) 
    .Where(Restrictions.Gt(Projections.Count<Task>(t => t.OrderId), 1)) 
    ; 

這將產生:

(SELECT this_0_.OrderId as y0_ 
    FROM [Task] this_0_ 
    GROUP BY this_0_.OrderId 
    HAVING count(this_0_.OrderId) > 1) 

現在我們可以使用它作爲外部SELECT子查詢:

Task task = null; 
var PendingTasks = 
    session.QueryOver<Task>(() => task) 
    // the WHERE clause: OrderId IN (subquery) 
    .WithSubquery 
    .WhereProperty(() => task.OrderId) 
    .In(subQuery) 

    // the rest of your SELECT/projections and transformation 
    .SelectList(list => list 
     .SelectGroup(b => b.OrderId) 
     .Select(b => b.TaskType) 
    )   
    .TransformUsing((Transformers.AliasToBean<TaskType>())) 
    .List<TaskType>() 
    ; 

這將創建其餘的,包括子查詢

+0

我喜歡那裏的分離。但在'.In(subQuery)'錯誤? 'NHibernate.Criterion.Lambda.QueryOverSubqueryPropertyBuilderBase ,Api.Task,Api.Task> .In (NHibernate.Criterion.QueryOver )'的類型參數不能被推斷從使用。嘗試明確指定類型參數。在子查詢中需要更多的分離? – jcc

+0

我展示的代碼片段爲我開箱即用。所以請檢查類型和命名空間或顯示堆棧跟蹤的完整代碼,請 –

+0

我更新了整個方法的問題,這是一個編譯錯誤。 – jcc