【问题标题】:Grouping without duplicating supplier row分组而不重复供应商行
【发布时间】:2015-06-22 23:30:58
【问题描述】:

使用 Linq-to-SQL 从 3 个表中获取 NorthWind 数据时遇到问题:

  1. Suppliers
  2. Products
  3. Categories

我想获取属于categoryId > 3 类别的所有产品的供应商。结果集将需要每个供应商 1 行,然后是一些子集,其中包含每个产品的一行,包括类别信息。这个想法是这个结果集将作为 ajax 调用的 json 值返回。

以下是我目前最简单的版本:

from sups in Suppliers
join prods in Products on sups.SupplierID equals prods.SupplierID
join cats in Categories on prods.CategoryID equals cats.CategoryID
where ( cats.CategoryID > 3)

group sups by sups.SupplierID into g
select g

在 LinqPad 中,结果集似乎包含许多重复的供应商。 有什么想法吗?

编辑: 感谢 Adduci 的回答,我最终得到了以下工作 LINQ 语句:

from sups in Suppliers
join prods in Products on sups.SupplierID equals prods.SupplierID
join cats in Categories on prods.CategoryID equals cats.CategoryID
where cats.CategoryID > 3
group new { sups, prods, cats } by new { sups.SupplierID, sups.CompanyName } into g
select new 
{
  g.Key,
  ProductInfo = from x in g
                 select new
                 {
                    ProductProperty = x.prods.ProductName,
                    CategoryProperty = x.cats.CategoryName
                 }  
}

额外的by new { sups.SupplierID, sups.CompanyName }完成了包括供应商字段的结果集。不错!

【问题讨论】:

    标签: c# .net linq linq-to-sql


    【解决方案1】:

    第一步是使用匿名类将 3 个表组合在一起

    group new { sups, prods, cats } 
    

    您应该像这样显式定义您想要的属性,而不是 select gIGrouping<...>):

    from sups in Suppliers
    join prods in Products on sups.SupplierID equals prods.SupplierID
    join cats in Categories on prods.CategoryID equals cats.CategoryID
    where cats.CategoryID > 3
    group new { sups, prods, cats } by sups.SupplierID into g
    select new 
    {
      Supplier = g.Key,
      ProductInfo = from x in g
                     select new
                     {
                        ProductProperty = x.prods.Prop1,
                        CategoryProperty = x.cats.Prop1
                     }  
    }
    

    这样可以防止从数据库返回未使用的信息

    【讨论】:

    • 我看到您已将 g.prods 的拼写错误修复为 x.prods。非常感谢!!完美运行!
    • 我刚刚意识到,这还有一个问题:供应商记录信息本身只包含键值和产品信息...可以扩展,与其他供应商属性(例如公司名称?)
    • @Paul0515 - 是的。您可以添加CompanyName = g.FirstOrDefault().sups.CompanyName或者您的方式可能会更好
    【解决方案2】:

    连接表时经常出现这种情况。你通常可以使用Distinct() 来解决这个问题。

    类似这样的:

    (from sups in Suppliers
    join prods in Products on sups.SupplierID equals prods.SupplierID
    join cats in Categories on prods.CategoryID equals cats.CategoryID
    where ( cats.CategoryID > 3)
    group sups by sups.SupplierID into g
    select g).Distinct()
    

    【讨论】:

    • 感谢您的建议,其中一个问题是将产品的属性和类别也放在同一行...
    猜你喜欢
    • 2020-04-12
    • 1970-01-01
    • 2020-09-20
    • 2021-11-16
    • 2010-11-26
    • 2017-09-28
    • 1970-01-01
    • 2016-03-12
    • 2023-02-07
    相关资源
    最近更新 更多