在上一个问题中,我询问如何获得客户第一笔订单,因此得到了回答:

var minOrders = from customer in DataSet.Customers
let order = (from o in DataSet.Orders where o.CustomerId == customer.CustomerId
order by o.OrderTimestamp
select o).first()
select new {
    customer.Name,
    order.OrderAmount
});


很好,但是如何在上面添加左外部联接?也就是说,即使没有订单,也要退回所有客户,例如:

var minOrders = from customer in DataSet.Customers LEFT OUTER JOIN
let order = (from o in DataSet.Orders where o.CustomerId == customer.CustomerId
order by o.OrderTimestamp
select o).first()
select new {
    customer.Name,
    order.OrderAmount
});


我知道,事后看来,我应该同时问这个问题。

谢谢乔

最佳答案

首先,首先使用let进行这样的连接并不理想。 LINQ中有一个join子句是有原因的:)

LINQ不特别支持左外部联接,但是您可以像这样伪造它们:

var minOrders = from customer in DataSet.Customers
                join order in DataSet.Orders.OrderBy(o => o.OrderTimestamp)
                     on customer.CustomerId equals o.CustomerId
                     into customerOrders
                let order = customerOrders.FirstOrDefault()
                select new {
                    customer.Name,
                    OrderAmount = order == null ? 0m : order.OrderAmount
                };


通常,左外部联接使用from foo in bar.DefaultIfEmpty而不是let foo = bar.FirstOrDefault(),但是在这种情况下,无论如何您只是在第一个匹配之后,因此采用了不同的方法。

我很确定这在逻辑上是可行的-SQL转换是否可以工作是另一回事。

10-02 08:32