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

また、feedbackTypeAlias.Idを返し、元のようにループでFeedbackType実行するのではなく、ステートメントからの完全なエンティティを返す方法を見つけたいと思います。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;

また、単一のクエリからDTOにデータを入力することもできましたがFeedbackTypeSummary、エンティティのエイリアスを作成する方法が見つからず、必要なプロパティのいくつかをに抽出することになりFeedbackTypeましたFeedackTypeSummary(とにかく行う方が良いでしょう)。

于 2013-01-24T19:53:47.343 に答える