LINQ Left Outer Join 与 Let 结合
在上一个问题中,我问如何获得客户第一订单,得到的回答是:
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
});
我知道,事后看来我应该同时问这个问题。
谢谢,乔
In a previous question I asked how I would get a Customers first Order, it was answered thus :
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
});
This is great, but how do I include a Left Outer Join onto the above? That is, return all Customers even if they have no orders, so something like :
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
});
I know, in hindsight I should of asked this at the same time..
Thanks, Joe
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,使用
let
进行这样的连接一开始并不理想。 LINQ 中存在join
子句是有原因的:)LINQ 中具体不支持左外连接,但您可以像这样伪造它们:
通常左外连接使用
from foo in bar.DefaultIfEmpty
而不是let foo = bar.FirstOrDefault()
但在这种情况下,无论如何您都只是在第一个匹配之后,因此采用了不同的方法。我非常确定这在逻辑上是有效的 - SQL 翻译是否有效是另一回事。
Firstly, using
let
to do the join like this isn't ideal in the first place. There's ajoin
clause in LINQ for a reason :)Left outer joins aren't specifically supported in LINQ, but you can fake them like this:
Usually a left outer join uses
from foo in bar.DefaultIfEmpty
instead oflet foo = bar.FirstOrDefault()
but in this case you're only after the first match anyway, hence the different approach.I'm pretty sure this works logically - whether the SQL translation will work or not is a different matter.