2010-07-08 47 views
1

我通过LINQ声明查询加入

from c in Categories 
join p in Products on c equals p.Category into ps 
select new { Category = new {c.CategoryID, c.CategoryName}, Products = ps }; 

然而,这会产生以下左外连接查询,并返回即使没有相关的产品的所有类别有以下组。

SELECT [t0].[CategoryID], [t0].[CategoryName], [t1].[ProductID], [t1].[ProductName],  [t1].[SupplierID], [t1].[CategoryID] AS [CategoryID2], [t1].[QuantityPerUnit], [t1].[UnitPrice], [t1].[UnitsInStock], [t1].[UnitsOnOrder], [t1].[ReorderLevel], [t1].[Discontinued], (
    SELECT COUNT(*) 
    FROM [Products] AS [t2] 
    WHERE [t0].[CategoryID] = [t2].[CategoryID] 
    ) AS [value] 
FROM [Categories] AS [t0] 
LEFT OUTER JOIN [Products] AS [t1] ON [t0].[CategoryID] = [t1].[CategoryID] 
ORDER BY [t0].[CategoryID], [t1].[ProductID] 

我真正想要的只是返回那些有关联产品的类别。但是,如果我重新写LINQ查询,像这样:

from c in Categories 
join p in Products on c equals p.Category 
group p by new {c.CategoryID, c.CategoryName} into ps 
select new { Category = ps.Key, Products = ps }; 

这让我对每个类别生成一个查询所需的结果,但

SELECT [t0].[CategoryID], [t0].[CategoryName] 
FROM [Categories] AS [t0] 
INNER JOIN [Products] AS [t1] ON [t0].[CategoryID] = [t1].[CategoryID] 
GROUP BY [t0].[CategoryID], [t0].[CategoryName] 
GO 

-- Region Parameters 
DECLARE @x1 Int SET @x1 = 1 
DECLARE @x2 NVarChar(9) SET @x2 = 'Beverages' 
-- EndRegion 
SELECT [t1].[ProductID], [t1].[ProductName], [t1].[SupplierID], [t1].[CategoryID], [t1].[QuantityPerUnit], [t1].[UnitPrice], [t1].[UnitsInStock], [t1].[UnitsOnOrder], [t1].[ReorderLevel], [t1].[Discontinued] 
FROM [Categories] AS [t0] 
INNER JOIN [Products] AS [t1] ON [t0].[CategoryID] = [t1].[CategoryID] 
WHERE (@x1 = [t0].[CategoryID]) AND (@x2 = [t0].[CategoryName]) 
GO 

-- Region Parameters 
DECLARE @x1 Int SET @x1 = 2 
DECLARE @x2 NVarChar(10) SET @x2 = 'Condiments' 
-- EndRegion 
SELECT [t1].[ProductID], [t1].[ProductName], [t1].[SupplierID], [t1].[CategoryID], [t1].[QuantityPerUnit], [t1].[UnitPrice], [t1].[UnitsInStock], [t1].[UnitsOnOrder], [t1].[ReorderLevel], [t1].[Discontinued] 
FROM [Categories] AS [t0] 
INNER JOIN [Products] AS [t1] ON [t0].[CategoryID] = [t1].[CategoryID] 
WHERE (@x1 = [t0].[CategoryID]) AND (@x2 = [t0].[CategoryName]) 
GO 

... 

是否有办法做等效的内部连接和组合,并且仍然只产生一个单一的查询,如组连接?

+0

are there Product.Categories or Category.Products List in your entities? – 2010-07-08 19:18:08

+0

我使用Northwind数据库表来编写查询。有Category.Products和Product.Category。类别产品关系是1到很多。 – 2010-07-08 22:25:13

回答

3
var queryYouWant = 
    from c in Categories 
    join p in Products on c equals p.Category 
    select new {Category = c, Product = p}; 

var result = 
    from x in queryYouWant.AsEnumerable() 
    group x.Product by x.Category into g 
    select new { Category = g.Key, Products = g }; 

有没有办法做一个内部的等效加入和组通过,仍然只能产生像一个单一查询该组加入?

不会。当您说GroupBy后跟非集合访问组元素时,这是一个重复的查询,其中组键是一个过滤器。

+0

谢谢。我认为必须有一种方法来获得我想要的结果,而不是首先将列表弄平然后分组,但是我猜我必须分两步来完成。 – 2010-07-16 18:01:31

2

该连接的目的是什么?

你原来的查询与此:

from c in Categories 
select new { Category = new { c.CategoryID, c.CategoryName }, c.Products } 

上午我莫名其妙地失去了一些东西明显???

如果只想类别的产品,那么这样做:

from c in Categories 
where c.Products.Any() 
select new { Category = new { c.CategoryID, c.CategoryName }, c.Products } 

或者,如果你想变平的结果:

from p in Products 
select new { p, p.Category.CategoryID, p.Category.CategoryName } 

后者将转化为内部或外部联接 - 取决于这种关系是否可以空。您可以强制内相当于加入如下:

from p in Products 
where p.Category != null 
select new { p, p.Category.CategoryID, p.Category.CategoryName } 
+0

你错过了一些东西,但我想这不是那么明显。我需要做一个连接,因为我运行查询的实际表没有FK关系。我只用Northwind表作为例子。我需要一个团队加入,我不想列出这个列表。因此问题的标题。换句话说,我希望结果返回一个类别,它是产品列表,但我不希望包含没有产品的类别。但关键点并不是真的,我是否可以在没有组的情况下运行查询,但是如何通过生成单个内部联接查询来完成组。 – 2010-07-10 13:29:58

+0

你的第二个查询是最有用的,但我可以使用ps.Any()过滤组,并且可以删除没有产品的类别,但它仍然是一个外连接。我想我很好奇,知道为什么我不能产生一个内联接,没有生成这么多的SQL查询。 – 2010-07-10 13:34:52