2013-01-24 57 views
2

我試圖將SQL語句轉換爲使用QueryOver(希望預先獲取響應的實體部分),但我無法弄清楚如何添加關聯Select語句的子查詢(我發現的所有示例都只使用Where子句中的子查詢顯示)。使用QueryOver將相關的子查詢添加到Select語句

這是我想要轉換的查詢:

var pendingFeedbackStatus = Session.QueryOver<FeedbackStatus>().Where(fs => fs.Name == "pending"); 
var projectWhereClause = project != null ? "AND f1.project_id = " + project.Id : ""; 

var query = Session.CreateSQLQuery(string.Format(@" 
     SELECT 
      ft.id as FEEDBACK_TYPE_ID, 
      (SELECT COUNT(*) FROM FEEDBACK f1 WHERE ft.id = f1.feedback_type_id AND f1.archive_ind = 0 {0}) as ALL_FEEDBACK_COUNT, 
      (SELECT COUNT(*) FROM FEEDBACK f1 WHERE ft.id = f1.feedback_type_id AND f1.archive_ind = 0 {0} AND feedback_status_id = {1}) as PENDING_FEEDBACK_COUNT 
     FROM feedback f 
     RIGHT JOIN feedback_type ft on f.feedback_type_id = ft.id WHERE ft.RESTRICTED_IND = 0 
     GROUP BY ft.id, ft.sort_order 
     ORDER BY ft.sort_order", 
     projectWhereClause, 
     pendingFeedbackStatus.Id 
    )) 
    .SetResultTransformer(Transformers.AliasToEntityMap); 

var results = query.List<IDictionary>(); 
return results.Select(r => 
    new FeedbackTypeSummary 
    { 
     Type = Get(Convert.ToInt32(r["FEEDBACK_TYPE_ID"])), 
     AllFeedbackCount = Convert.ToInt32(r["ALL_FEEDBACK_COUNT"]), 
     PendingFeedbackCount = Convert.ToInt32(r["PENDING_FEEDBACK_COUNT"]) 
    }).ToList(); 

和這裏是我到目前爲止有(其中大部分是一切減去相關子查詢和一些額外的過濾添加到子查詢):

var pendingFeedbackStatus = Session.QueryOver<FeedbackStatus>().Where(fs => fs.Name == "pending"); 

Feedback feedbackAlias = null; 
FeedbackType feedbackTypeAlias = null; 

var allFeedback = QueryOver.Of<Feedback>() 
    .Where(f => f.Type.Id == feedbackTypeAlias.Id) 
    .Where(f => !f.IsArchived); 

var pendingFeedback = QueryOver.Of<Feedback>() 
    .Where(f => f.Type.Id == feedbackTypeAlias.Id) 
    .Where(f => !f.IsArchived) 
    .Where(f => f.Status.Id == pendingFeedbackStatus.Id); 

var foo = Session.QueryOver<Feedback>(() => feedbackAlias) 
    .Right.JoinAlias(f => f.Type,() => feedbackTypeAlias, ft => !ft.IsRestricted) 
    .SelectList(list => list 
     // TODO: Add correlated subqueries here? 
     .SelectGroup(() => feedbackTypeAlias.Id) 
     .SelectGroup(() => feedbackTypeAlias.SortOrder) 
    ) 
    .OrderBy(() => feedbackTypeAlias.SortOrder).Asc; 

var test = foo.List<object[]>(); 

我也想找到一種方法,返回的從聲明的,而不是返回feedbackTypeAlias.Id,然後不得不在一個循環中執行Type = Get(Convert.ToInt32(r["FEEDBACK_TYPE_ID"])),因爲我在原來做了充分的FeedbackType實體。

回答

2

我覺得我找了這10次,但我忽略了提供所需的相關子查詢的.SelectSubQuery()方法。這個答案讓我失望 - https://stackoverflow.com/a/8143684/191902

以下是完整的QueryOvery版本:

var pendingFeedbackStatus = Session.QueryOver<FeedbackStatus>().Where(fs => fs.Name == "pending").SingleOrDefault(); 

Domain.Feedback.Feedback feedbackAlias = null; 
FeedbackType feedbackTypeAlias = null; 
var allFeedback = QueryOver.Of<Domain.Feedback.Feedback>() 
    .Where(f => f.Type.Id == feedbackTypeAlias.Id) 
    .Where(f => !f.IsArchived); 

var pendingFeedback = QueryOver.Of<Domain.Feedback.Feedback>() 
    .Where(f => f.Type.Id == feedbackTypeAlias.Id) 
    .Where(f => !f.IsArchived) 
    .Where(f => f.Status.Id == pendingFeedbackStatus.Id); 

if (project != null) 
{ 
    allFeedback.Where(f => f.Project.Id == project.Id); 
    pendingFeedback.Where(f => f.Project.Id == project.Id); 
} 

FeedbackTypeSummary result = null; 
var query = Session.QueryOver<Domain.Feedback.Feedback>(() => feedbackAlias) 
    .Right.JoinAlias(f => f.Type,() => feedbackTypeAlias, ft => !ft.IsRestricted) 
    .SelectList(list => list 
     .SelectSubQuery(allFeedback.ToRowCountQuery()).WithAlias(() => result.AllFeedbackCount) 
     .SelectSubQuery(pendingFeedback.ToRowCountQuery()).WithAlias(() => result.PendingFeedbackCount) 
     .SelectGroup(() => feedbackTypeAlias.Id).WithAlias(() => result.TypeId) 
     .SelectGroup(() => feedbackTypeAlias.Name).WithAlias(() => result.TypeName) 
     .SelectGroup(() => feedbackTypeAlias.NamePlural).WithAlias(() => result.TypeNamePlural) 
     .SelectGroup(() => feedbackTypeAlias.SortOrder) 
    ) 
    .OrderBy(() => feedbackTypeAlias.SortOrder).Asc 
    .TransformUsing(Transformers.AliasToBean<FeedbackTypeSummary>()); 

var results = query.List<FeedbackTypeSummary>(); 
return results; 

我還能夠從單個查詢填充我FeedbackTypeSummary DTO,雖然我不能找到一種方法,別名一個實體,最終提取幾從FeedbackTypeFeedackTypeSummary(這可能是一個更好的事情做反正)所需的屬性。

+0

你回答了你自己的問題......你是男人! – matao