NHibernate投影:如何创建AliasToBean投影?

时间:2013-07-12 17:50:10

标签: nhibernate queryover nhibernate-projections

我正在尝试将这个效率低下的查询转换为投影到dto的查询。 原始查询如下所示:

var flatFeePolicies = _session.QueryOver<FlatChargeAccessFee>(() => flatChargeAccessFeeAlias)
                                .JoinAlias(x => x.AgreementAccessFee, () => agreementAccessFeeAlias)
                                .JoinQueryOver(x => x.ClientPolicy, () => clientPolicyAlias)
                                .Where(y => agreementAccessFeeAlias.Agreement.Id == request.AgreementId)
                                .List()
                                .Select(x => new FlatChargeAccessFeeInfo()
                                    {
                                        FlatChargeAccessFeeId = x.Id,
                                        ClientName = x.ClientPolicy.Bid.Client.Name,
                                        PolicyNumber = x.ClientPolicy.PolicyNumber,
                                        ClientPolicyId = x.ClientPolicy.Id,
                                        AgreementAccessFeeId = x.AgreementAccessFee.Id,
                                        ShouldCheckBeGenerated = x.ShouldCheckBeGenerated,
                                        MonthlyFee = x.MontlyFeeAmount.Amount.ToString(),
                                        PolicyYear = x.ClientPolicy.PolicyNumber.Year
                                    })
                                .ToList();

我试过这样:

var flatFeePolicies = _session.QueryOver<FlatChargeAccessFee>(() => flatChargeAccessFeeAlias)
                              .JoinAlias(x => x.AgreementAccessFee, () => agreementAccessFeeAlias)
                              .JoinQueryOver(x => x.ClientPolicy, () => clientPolicyAlias)
                              .Where(y => agreementAccessFeeAlias.Agreement.Id == request.AgreementId)
                              .SelectList(list => list
                                                      .Select(x => x.Id).WithAlias(() => feeInfo.FlatChargeAccessFeeId)
                                                      .Select(x => x.ClientPolicy.Bid.Client.Name).WithAlias(() => feeInfo.ClientName)
                                                      .Select(x => x.ClientPolicy.PolicyNumber).WithAlias(() => feeInfo.PolicyNumber)
                                                      .Select(x => x.ClientPolicy.Id).WithAlias(() => feeInfo.ClientPolicyId)
                                                      .Select(x => x.AgreementAccessFee.Id).WithAlias(() => feeInfo.AgreementAccessFeeId)
                                                      .Select(x => x.ShouldCheckBeGenerated).WithAlias(() => feeInfo.ShouldCheckBeGenerated)
                                                      .Select(x => x.MontlyFeeAmount.Amount.ToString()).WithAlias(() => feeInfo.MonthlyFee)
                                                      .Select(x => x.ClientPolicy.PolicyNumber.Year).WithAlias(() => feeInfo.PolicyYear)
                               )
                               .TransformUsing(Transformers.AliasToBean<FlatChargeAccessFeeInfo>())
                               .List<FlatChargeAccessFeeInfo>();

我收到的错误是变量“x”已在范围内引用但未定义。转换它的正确语法是什么?

在安德鲁的帮助下,这是正确的版本

ClientPolicy clientPolicyAlias = null;
Client clientAlias = null;
Bid bidAlias = null;
AgreementAccessFee agreementAccessFeeAlias = null;
FlatChargeAccessFee flatChargeAccessFeeAlias = null;
FlatChargeAccessFeeInfo feeInfo = null;


var flatFeePolicies = _session.QueryOver<FlatChargeAccessFee>(() => flatChargeAccessFeeAlias)
                              .JoinAlias(a => a.AgreementAccessFee, () => agreementAccessFeeAlias)
                              .JoinQueryOver(b => b.ClientPolicy, () => clientPolicyAlias)
                              .JoinAlias(b=>b.Bid,()=>bidAlias)
                              .JoinAlias(b=>b.Client, ()=>clientAlias)
                              .Where(c => agreementAccessFeeAlias.Agreement.Id == request.AgreementId)

                              .SelectList(list => list
                                                      .Select(d => d.Id).WithAlias(() => feeInfo.FlatChargeAccessFeeId)
                                                      .Select(e => clientAlias.Name).WithAlias(() => feeInfo.ClientName)
                                                      .Select(e => clientAlias.Number).WithAlias(() => feeInfo.ClientNumber)
                                                      .Select(f => bidAlias.OptionNumber).WithAlias(() => feeInfo.BidOptionNumber)
                                                      .Select(f => bidAlias.Year).WithAlias(()=>feeInfo.PolicyYear)
                                                      .Select(g => clientPolicyAlias.Id).WithAlias(() => feeInfo.ClientPolicyId)
                                                      .Select(h => agreementAccessFeeAlias.Id).WithAlias(() => feeInfo.AgreementAccessFeeId)
                                                      .Select(j => j.ShouldCheckBeGenerated).WithAlias(() => feeInfo.ShouldCheckBeGenerated)
                                                      .Select(k => k.MontlyFeeAmount.Amount).WithAlias(()=>feeInfo.MonthlyFee)

                               )
                               .TransformUsing(Transformers.AliasToBean<FlatChargeAccessFeeInfo>())
                               .List<FlatChargeAccessFeeInfo>();

1 个答案:

答案 0 :(得分:1)

你很亲密,但有一些事情:

  • 此选择:

    .Select(x => x.MontlyFeeAmount.Amount.ToString()).WithAlias(() => feeInfo.MonthlyFee)
    

    不起作用。 QueryOver尝试将您的代码直接转换为SQL。如果该属性不作为数据库中的列存在,则查询将无法正常工作(除非您使用映射的自定义类型,QueryOver可以处理这些类型)

  • 嵌套属性访问也不起作用:

    .Select(x => x.ClientPolicy.Bid.Client.Name).WithAlias(() => feeInfo.ClientName)
    

    由于上面列出的类似原因。 QueryOver将尝试将您的属性访问权限直接转换为SQL。您需要明确加入ClientPolicyBidClient

一般情况下,请记住您正在编写将转换为SQL的代码。实际上,我通常会编写我想要生成 first 的SQL,然后编写与之对应的QueryOver。希望有所帮助!