2

我正在尝试将 SQL 语句转换为使用 QueryOver(希望预取响应的实体部分),但我无法弄清楚如何将相关子查询添加到 Select 语句(我发现的所有示例仅显示在 Where 子句中使用子查询)。

这是我要转换的查询:

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[]>();

我还想找到一种FeedbackType从语句中返回完整实体的方法,而不是返回 feedbackTypeAlias.Id 然后必须Type = Get(Convert.ToInt32(r["FEEDBACK_TYPE_ID"]))像我在原始语句中那样在循环中执行。

4

1 回答 1

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,尽管我找不到为实体命名的方法并最终从FeedbackTypeinto中提取了一些所需的属性FeedackTypeSummary(无论如何这可能是更好的做法)。

于 2013-01-24T19:53:47.343 回答