C# LINQ-Can';t在不更改多表分组的情况下向结果中添加列

C# LINQ-Can';t在不更改多表分组的情况下向结果中添加列,c#,linq,group-by,C#,Linq,Group By,假设我有一个“数据库”,定义为: // Baked goods vendors var vendor = new[] { new { ID = 1, Baker = "Pies R Us", StMnemon = "NY", Items = 8, Rating = 9 }, new { ID = 2, Baker = "Mikes Muffins", StMnemon = "CA", Items = 5, Rating = 9 }, new { ID = 3, Ba

假设我有一个“数据库”,定义为:

// Baked goods vendors
   var vendor = new[] {
    new { ID = 1, Baker = "Pies R Us", StMnemon = "NY", Items = 8, Rating = 9 },
    new { ID = 2, Baker = "Mikes Muffins", StMnemon = "CA", Items = 5, Rating = 9 },
    new { ID = 3, Baker = "Best Bakers", StMnemon = "FL", Items = 2, Rating = 5 },
    new { ID = 4, Baker = "Marys Baked Treats", StMnemon = "NY", Items = 8, Rating = 7 },
    new { ID = 5, Baker = "Cool Cakes", StMnemon = "NY", Items = 4, Rating = 9 },
    new { ID = 6, Baker = "Pie Heaven", StMnemon = "CA", Items = 12, Rating = 9 },
    new { ID = 7, Baker = "Cakes N More", StMnemon = "GA", Items = 6, Rating = 8 },
    new { ID = 8, Baker = "Dream Desserts", StMnemon = "FL", Items = 2, Rating = 7 }
};

// Locations
var location = new[] {
    new {ID= 1, State = "New York", Mnemonic = "NY"},
    new {ID= 2, State = "Massachusetts", Mnemonic = "MA"},
    new {ID= 3, State = "Ohio", Mnemonic = "OH"},
    new {ID= 4, State = "California", Mnemonic = "CA"},
    new {ID= 5, State = "Florida", Mnemonic = "FL"},
    new {ID= 6, State = "Texas", Mnemonic = "TX"},
    new {ID= 7, State = "Georgia", Mnemonic = "GA" }
};
我想构建一个与SQL查询等效的查询:

SELECT   State, Rating, SUM(Items) AS 'Kinds'
FROM     vendor, location
WHERE    vendor.StMnemon = location.Mnemonic
GROUP BY State, Rating
var result = from v in vendor
             from l in location
             where l.Mnemonic == v.StMnemon
             group v by new { l.State, v.Rating } into grp
             orderby grp.Key.Rating ascending, grp.Key.State
             select new {State = grp.Key.State, Rating = grp.Key.Rating, Kinds = grp.Sum(p=>p.Items)};

foreach (var item in result)
        Console.WriteLine("{0}\t{1}\t{2}", item.State, item.Rating, item.Kinds);
此查询中有两件有趣的事情:

  • 分组依据涉及多个表,并且
  • 结果包含分组条件中未出现的列的总和
  • 我在和上的帖子中看到了解决方案。问题是,将两者结合起来并不能真正复制关系查询

    我尝试用以下代码在LINQ中复制它:

    var query = from v in vendor
               join l in location
               on v.StMnemon equals l.Mnemonic
               orderby v.Rating ascending, l.State
               select new { v, l };
    
    var result = from q in query
               group q by new { 
                   s = q.l.State, 
                   r = q.v.Rating
    /* ==> */    , i = q.v.Items
               } into grp
            select new 
            {
                State = grp.Key.s,
                Rating = grp.Key.r
    /* ==> */ , Kinds = grp.Sum(k => grp.Key.i)
            };
    
    这导致:

    =================================
    State           Rating  Kinds
    Florida         5       2
    Florida         7       2
    New York        7       8
    Georgia         8       6
    California      9       5
    California      9       12
    New York        9       8
    New York        9       4
    =================================
    
    鉴于,上面给出的SQL查询给出了以下结果:

    =========================
    State       Rating  Kinds
    Florida     5       2
    Florida     7       2
    New York    7       8
    Georgia     8       6
    California  9       17
    New York    9       12
    =========================
    
    这种差异是因为除了分组标准之外,似乎没有地方放置其他列,这当然会改变分组结果。注释掉上面代码中/*==>*/注释所指示的两行将给出与SQL结果相同的分组,但这当然会删除我想要包含的求和字段


    我们如何在LINQ中对多个表进行分组,并在不更改分组结果的情况下包含其他条件?

    类似的内容似乎返回与SQL查询相同的结果:

    SELECT   State, Rating, SUM(Items) AS 'Kinds'
    FROM     vendor, location
    WHERE    vendor.StMnemon = location.Mnemonic
    GROUP BY State, Rating
    
    var result = from v in vendor
                 from l in location
                 where l.Mnemonic == v.StMnemon
                 group v by new { l.State, v.Rating } into grp
                 orderby grp.Key.Rating ascending, grp.Key.State
                 select new {State = grp.Key.State, Rating = grp.Key.Rating, Kinds = grp.Sum(p=>p.Items)};
    
    foreach (var item in result)
            Console.WriteLine("{0}\t{1}\t{2}", item.State, item.Rating, item.Kinds);
    

    类似的内容似乎返回与SQL查询相同的结果:

    SELECT   State, Rating, SUM(Items) AS 'Kinds'
    FROM     vendor, location
    WHERE    vendor.StMnemon = location.Mnemonic
    GROUP BY State, Rating
    
    var result = from v in vendor
                 from l in location
                 where l.Mnemonic == v.StMnemon
                 group v by new { l.State, v.Rating } into grp
                 orderby grp.Key.Rating ascending, grp.Key.State
                 select new {State = grp.Key.State, Rating = grp.Key.Rating, Kinds = grp.Sum(p=>p.Items)};
    
    foreach (var item in result)
            Console.WriteLine("{0}\t{1}\t{2}", item.State, item.Rating, item.Kinds);
    

    您可以在组外进行聚合:

    var query = from v in vendor
               join l in location
               on v.StMnemon equals l.Mnemonic
               orderby v.Rating ascending, l.State
               select new { v, l };
    
    var result = from q in query
               group q by new { 
                   s = q.l.State, 
                   r = q.v.Rating
               } into grp
            select new 
            {
                State = grp.Key.s,
                Rating = grp.Key.r,
                Kinds = grp.Sum(g => g.Items)
            };
    

    分组有点难理解-它返回一个
    i分组
    ,该分组有一个属性-
    。该分组中的实际项目由
    GetEnumerator()
    函数返回,该函数允许您将该组视为这些项目的集合,这意味着您可以对该组中的项目进行聚合。

    您可以在组外进行聚合:

    var query = from v in vendor
               join l in location
               on v.StMnemon equals l.Mnemonic
               orderby v.Rating ascending, l.State
               select new { v, l };
    
    var result = from q in query
               group q by new { 
                   s = q.l.State, 
                   r = q.v.Rating
               } into grp
            select new 
            {
                State = grp.Key.s,
                Rating = grp.Key.r,
                Kinds = grp.Sum(g => g.Items)
            };
    
    分组有点难理解-它返回一个
    i分组
    ,该分组有一个属性-
    。该分组中的实际项目由
    GetEnumerator()
    函数返回,该函数允许您将该组视为这些项目的集合,这意味着您可以对该组中的项目进行聚合