这是一个简单的LINQ查询(基于NorthWind),它返回一个Customers列表。每个客户都包含订单列表。
from c in Customers
join o in Orders on c.CustomerID equals o.CustomerID into CO
select new {c, CO}
这很好用,生成的SQL也没问题。现在我想更进一步。我希望每个Order对象都包含OrderDetails列表。我使用以下查询:
from c in Customers
join od in (
from o in Orders
join od in OrderDetails on o.OrderID equals od.OrderID into OD
select new { o.CustomerID, o, OD }
)
on c.CustomerID equals od.CustomerID into COD
select new { c, COD }
此查询有效,但会生成可怕的SQL。为每个客户发出单独的查询。当你查看我们的lambda代码时:
Customers
.GroupJoin (
Orders
.GroupJoin (
OrderDetails,
o => o.OrderID,
od => od.OrderID,
(o, OD) =>
new
{
CustomerID = o.CustomerID,
o = o,
OD = OD
}
),
c => c.CustomerID,
od => od.CustomerID,
(c, COD) =>
new
{
c = c,
COD = COD
}
)
嵌套的GroupJoins似乎是多个SQL stataments的原因。但是,我尝试了各种组合而没有成功。有什么想法吗?
编辑: 我可能有点不清楚我想要实现的目标。我希望OrderDetail对象是Order对象的属性,而Order对象又是Customer对象的属性。我不想订购& OrderDetail是Customer的属性。我想获得独特客户的名单。对于每个客户,我期望订单列表和每个订单我想要一个OrderDetails列表。我希望层次结构比原始查询更深一层。
答案 0 :(得分:1)
如果要强制执行单个查询,则可以在客户端执行分组,而不是在服务器端执行分组:
from a in (from c in Customers
join o in Orders on c.CustomerID equals o.CustomerID
join od in OrderDetails on o.OrderID equals od.OrderID
select new {c, o, od}).AsEnumerable()
group a by a.c into g
select new { Customer = g.Key, Orders = g.Select(o => o.o) , OrderDetails = g.Select(od => od.od)}
生成的SQL是:
SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax], [t1].[OrderID], [t1].[CustomerID] AS [CustomerID2], [t1].[EmployeeID], [t1].[OrderDate], [t1].[RequiredDate], [t1].[ShippedDate], [t1].[ShipVia], [t1].[Freight], [t1].[ShipName], [t1].[ShipAddress], [t1].[ShipCity], [t1].[ShipRegion], [t1].[ShipPostalCode], [t1].[ShipCountry], [t2].[OrderID] AS [OrderID2], [t2].[ProductID], [t2].[UnitPrice], [t2].[Quantity], [t2].[Discount]
FROM [Customers] AS [t0]
INNER JOIN [Orders] AS [t1] ON [t0].[CustomerID] = [t1].[CustomerID]
INNER JOIN [Order Details] AS [t2] ON [t1].[OrderID] = [t2].[OrderID]
请记住,这比多次查询不更快,同时会增加网络和服务器负载。
我的建议是使用如下查询:
DataLoadOptions opt = new DataLoadOptions();
opt.LoadWith<Orders>(o => o.OrderDetails);
this.LoadOptions = opt;
from c in Customers
select new {c, Orders = c.Orders, OrderDetails = c.Orders.SelectMany( o=> o.OrderDetails)}
答案 1 :(得分:0)
为什么不使用多个连接:
from c in Customers
join o in Orders on c.CustomerID equals o.CustomerID
join od in OrderDetails on o.OrderID equals od.OrderID
select new {c, o, od}
答案 2 :(得分:0)
您可能尝试加入服务器上的OrderDetails,然后在客户端上“重新组合”以获得完整的分层数据结构:
var q = from c in Customers
join o in Orders on c.CustomerID equals o.CustomerID
join od in OrderDetails on o.OrderID equals od.OrderID into OD
select new { c, o, OD };
var res = from x in q.AsEnumerable()
group x by x.c.CustomerID into g
select new
{
Customer = g.First().c,
Orders = g.Select(y => new
{
Order = y.o,
OrderDetails = y.OD
})
};
答案 3 :(得分:0)