编写linq查询以将具有重复ID的元素一起添加

时间:2013-08-02 16:28:11

标签: linq linq-to-sql

我正在尝试将一些sql转换为某些linq,并遇到一些麻烦。

我有一个包含3列的表,我们称之为MfrID,CatID和Count。

我希望能够为某些方法提供一个CatID列表,它将遍历该表,找到该列表中包含CatID的所有MfrID和Counts,并将mfrID相等的计数加在一起,然后通过新的TotalCounts对表格进行排序,然后返回前X个结果。

我觉得最好在代码中解释,这是一个我试图解决的样本测试

     [TestMethod]
    public void tempFiguringOutLinqQuery()
    {
        //some example data of what a sql table could look like
        var sampleData = new []
            {
                new {MfrId = 1, CatId = 1, MfrCount = 3},
                new {MfrId = 1, CatId = 2, MfrCount = 1},
                new {MfrId = 5, CatId = 1, MfrCount = 2},
                new {MfrId = 5, CatId = 6, MfrCount = 20},
                new {MfrId = 3, CatId = 5, MfrCount = 14},
                new {MfrId = 3, CatId = 2, MfrCount = 7},
                new {MfrId = 3, CatId = 1, MfrCount = 9},
                new {MfrId = 2, CatId = 1, MfrCount = 1}
            }.ToList();

        var catList = new List<int> {1, 2};

        //where CatIDList.Contains(1 or 2), Add MfrCount where MfrIds are equal, then take the top 3 results ordered by mfrCountDescending
        //ughhhhh
        var results = sampleData.Where(w => catList.Contains(w.CatId)).GroupBy(g => g.MfrCount); 

        //expected results
        // { MfrId = 3, MfrCount = 16 }
        // { MfrId = 1, MfrCount = 4 }
        // { MfrId = 5, MfrCount = 2 }
        Assert.Inconclusive();
    }

2 个答案:

答案 0 :(得分:2)

最简单的方法是按制造商ID分组,然后对每个组应用转换。你在那里几乎,只是按错误的字段分组并错过转换。例如,包括排序和“进入前三名”我们得到:

var results = sampleData.Where(w => catList.Contains(w.CatId))
                        .GroupBy(w => w.MfrId) // Not MfrCount!
                        .Select(g => new { MfrId = g.Key,
                                           MfrCount = g.Sum(x => x.MfrCount) })
                        .OrderByDescending(x => x.MfrCount)
                        .Take(3);

GroupBy的重载实际上需要进行小组投影,但我个人觉得阅读Select分开的版本更简单。

答案 1 :(得分:1)

MfrId分组过滤数据(这将是组密钥),并为每个组计算MfrCount的总和:

var query = from d in sampleData
            where catList.Contains(d.CatId)
            group d by d.MfrId into g
            select new {
               MfrId = g.Key,
               MfrCount = g.Sum(x => x.MfrCount)
            };

var result = query.OrderByDescending(x => x.MfrCount).Take(3);

或者用流利的语法:

var result = sampleData.Where(d => catList.Contains(d.CatId))
                       .GroupBy(d => d.MfrId)
                       .Select(g => new {
                           MfrId = g.Key,
                           MfrCount = g.Sum(x => x.MfrCount)
                       })
                       .OrderByDescending(x => x.MfrCount)
                       .Take(3);

结果:

{ MfrId = 3, MfrCount = 16 }
{ MfrId = 1, MfrCount = 4 }
{ MfrId = 5, MfrCount = 2 }

编辑:错过了您只需要前3个结果,为查询添加了Take(3)