两个与实体框架lambda中的同一个表的不同子句连接

时间:2018-01-26 09:51:03

标签: c# sql-server entity-framework lambda

我正在尝试将SQL查询转换为lambda表达式。

SQL查询如下所示:

select 
    po.OrderID as order_number,
    pc.emailaddress as user_email,
    pc.CustomerID as customer_code,
    pb.DisplayName as bank,
    poab.street1 + ' ' + poab.Street2 as 'billing_address',
    po.createdate as 'created_date',
    'tr' as currency,
    po.TotalPrice - po.TotalPromotionPrice as discount_amount,
    null as 'extra_field',
    pbi.InstalmentCount as installment_count,
    pp.DisplayName as payment_type,
    poas.street1 + ' ' + poas.street2 as 'shipping_address',
    'UPS' as shipping_company,
    pos.Displayname as status,
    po.ShipmentReferenceNo as 'tracking_number'
from
    PrmOrder po
inner join 
    prmcustomer pc on po.CustomerID = pc.customerid
inner join 
    PrmBank pb on po.BankId = pb.BankId
inner join 
    prmorderaddress poab on po.orderid = poab.orderid and poab.isbillingaddress = 1
left join 
    PrmBankInstalment pbi on pbi.BankInstalmentID = po.BankInstalmentID
inner join 
    PrmPaymentType pp on po.PaymentTypeID = pp.PaymentTypeId
inner join 
    prmorderaddress poas on po.orderid = poas.orderid and poas.isshippingaddress = 1
inner join 
    prmorderstatus pos on po.orderstatusid = pos.orderstatusid

由于这两个表之间的一对多连接以及我需要显示两条线,我内部加入了同一个表两次。基本上,OrderID可以在OrderAddress表上有两个记录,一个用于记帐地址,另一个用于发货地址。它在SQL上运行良好但我无法将其转换为lambda表达式。

我先尝试过这样的事情;

var OrderHeader = db.PrmOrders
                .Include(x => x.PrmCustomer)
                .Include(x => x.PrmBank)
                .Include(x => x.PrmOrderAddresses)
                .Include(x => x.PrmBankInstalment)
                .Include(x => x.PrmPaymentType)
                .Include(x => x.PrmOrderStatu)
                .Where(x => x.PrmCustomer.EmailAddress != null && x.OrderStatusID != 1 && x.OrderID > OrderID)
                .OrderBy(x => x.OrderID)
.Select(x => new HeaderDTO()
             {
                 order_number = x.OrderID,
                 user_email = x.PrmCustomer.EmailAddress,
                 customer_code = x.PrmCustomer.CustomerID,
                 order_amount = x.GrandTotal,
                 bank = x.PrmBank.DisplayName,
                 billing_address = x.PrmOrderAddresses
                                     .Where(c => c.IsBillingAddress == true && c.OrderID == x.OrderID)
                                     .Select(c => c.Street1 + " " + c.Street2).ToString(),
                 created_date = x.OrderDate,
                 currency = "TRY",
                 discount_amount = x.TotalPrice - x.TotalPromotionPrice,
                 installment_count = x.PrmBankInstalment.InstalmentCount == null ? 0 : x.PrmBankInstalment.InstalmentCount,
                 payment_type = x.PrmPaymentType.DisplayName,
                 shipping_address = x.PrmOrderAddresses
                                     .Where(c => c.IsShippingAddress == true & c.OrderID == x.OrderID)
                                     .Select(c => c.Street1 + " " + c.Street2 + " " + c.PrmAddressCity.DisplayName + " " + c.PrmAddressCountry.DisplayName).ToString(),
                 shipping_company = "UPS",
                 status = x.PrmOrderStatu.DisplayName,
                 tracking_number = x.ShipmentReferenceNo == null ? "" : x.ShipmentReferenceNo
             });

这导致V alues of type 'collection[Edm.String(Nullable=True,DefaultValue=,MaxLength=,Unicode=,FixedLength=)]' can not be converted to string.错误,并且Edmx中的删除/重新添加表不起作用,如建议的那样。

所以现在我正在尝试使用Lambda表达式进行三重连接,它感觉不太正常,看起来有点混乱

var OrderHeader = db.PrmOrders
                .Include(x => x.PrmCustomer)
                .Include(x => x.PrmBank)
                .Include(x => x.PrmOrderAddresses)
                .Include(x => x.PrmBankInstalment)
                .Include(x => x.PrmPaymentType)
                .Include(x => x.PrmOrderStatu)
                .Where(x => x.PrmCustomer.EmailAddress != null && x.OrderStatusID != 1 && x.OrderID > OrderID)
                .OrderBy(x => x.OrderID)
                .Join(db.PrmOrderAddresses.Where(a => a.IsBillingAddress == true), x => x.OrderID, a => a.OrderID, (x, a) => new
                {
                    BillingAddress = a.Street1 + " " + a.Street2 + " " + a.PrmAddressCity.DisplayName + " " + a.PrmAddressCountry.DisplayName,
                    OrderID = x.OrderID
                })
                .Join(db.PrmOrderAddresses.Where(a => a.IsShippingAddress == true), x => x.OrderID, s => s.OrderID, (x, s) => new
                {
                    order_number = x.OrderID,
                    user_email = x.PrmCustomer.EmailAddress,
                    customer_code = x.PrmCustomer.CustomerID,
                    order_amount = x.GrandTotal,
                    bank = x.PrmBank.DisplayName,
                    //billing_address = x.PrmOrderAddresses
                    //                    .Where(c => c.IsBillingAddress == true && c.OrderID == x.OrderID)
                    //                    .Select(c => c.Street1 + " " + c.Street2).ToString(),
                    created_date = x.OrderDate,
                    currency = "TRY",
                    discount_amount = x.TotalPrice - x.TotalPromotionPrice,
                    installment_count = x.PrmBankInstalment.InstalmentCount == null ? 0 : x.PrmBankInstalment.InstalmentCount,
                    payment_type = x.PrmPaymentType.DisplayName,
                    //shipping_address = x.PrmOrderAddresses
                    //                    .Where(c => c.IsShippingAddress == true & c.OrderID == x.OrderID)
                    //                    .Select(c => c.Street1 + " " + c.Street2 + " " + c.PrmAddressCity.DisplayName + " " + c.PrmAddressCountry.DisplayName).ToString(),
                    shipping_company = "UPS",
                    status = x.PrmOrderStatu.DisplayName,
                    tracking_number = x.ShipmentReferenceNo == null ? "" : x.ShipmentReferenceNo
                    ShippingAddress = s.Street1 + " " + s.Street2 + " " + s.PrmAddressCity.DisplayName + " " + s.PrmAddressCountry.DisplayName
                });

我如何实现我的目标?

1 个答案:

答案 0 :(得分:2)

正如错误消息告诉您的那样,您无法将表达式转换为字符串,它没有任何意义。
如果有多个项目,您必须决定使用First / FirstOrDefault,如果总是有一个项目,则需要var OrderHeader = db.PrmOrders .Where(x => x.PrmCustomer.EmailAddress != null && x.OrderStatusID != 1 && x.OrderID > OrderID) .OrderBy(x => x.OrderID) .Select(x => new HeaderDTO { order_number = x.OrderID, user_email = x.PrmCustomer.EmailAddress, customer_code = x.PrmCustomer.CustomerID, order_amount = x.GrandTotal, bank = x.PrmBank.DisplayName, billing_address = x.PrmOrderAddresses .Where(c => c.IsBillingAddress && c.OrderID == x.OrderID) .Select(c => c.Street1 + " " + c.Street2) .ToList() / .First() / .FirstOrDefault(), created_date = x.OrderDate, currency = "TRY", discount_amount = x.TotalPrice - x.TotalPromotionPrice, installment_count = x.PrmBankInstalment.InstalmentCount == null ? 0 : x.PrmBankInstalment.InstalmentCount, payment_type = x.PrmPaymentType.DisplayName, shipping_address = x.PrmOrderAddresses .Where(c => c.IsShippingAddress && c.OrderID == x.OrderID) .Select(c => c.Street1 + " " + c.Street2 + " " + c.PrmAddressCity.DisplayName + " " + c.PrmAddressCountry.DisplayName) .ToList() / .First() / .FirstOrDefault(), shipping_company = "UPS", status = x.PrmOrderStatu.DisplayName, tracking_number = x.ShipmentReferenceNo == null ? "" : x.ShipmentReferenceNo }); ;如果没有项目,则需要>> xmlread() warning: the 'xmlread' function is not yet implemented in Octave Please read <http://www.octave.org/missing.html> to learn how you can contribute missing functionality. error: 'xmlread' undefined near line 1 column 1

io