将GroupBy用于多列并返回列表<tsource>

时间:2017-06-01 08:24:09

标签: c#

在这个article中,它展示了我们如何在lambda表达式中对多个列进行分组。但是它返回IEnumerable<IEnumerable<TSource>>,这不是我想要实现的结果。

我创建了一个包含一些属性的类。

internal class Class1
{
    internal string prop1 { get; set; }
    internal string prop2 { get; set; }
    internal decimal? prop3 { get; set; }
}

现在,如果我创建以下lambda表达式,它将返回IQueryable<IEnumerable<Class1>> listClass1

var listClass1 = context.Table1
    .Join(context.Table2,
            t1 => t1.Id,
            t2 => t2.Table1Id,
            (t1, t2) => new { t1, t2 })
    .Where(/*some expressions here*/)
    .GroupBy(data => new
    {
        data.t1.Column1,
        data.t2.Column2,
    })
    .Select(data => data.Select(x => new Class1
    {
        prop1 = x.t1.Column1,
        prop2 = x.t2.Column2,
        prop3 = x.t1.Column3
    }));

但我想要的是 List<Class1> listClass1 ,因为我打算使用foreach来迭代列表中的每个元素。这可能吗?

1 个答案:

答案 0 :(得分:0)

然后你不应该使用GroupBy()GroupBy()的目标是将单个项目列表拆分为多个项目列表 项目的分配基于相等的键值发生。在您的情况下,密钥由多个列组成,但原则保持不变。

SelectMany()GroupBy()相反。它从多个不同的列表中创建一个列表。

您问题的直接答案是,您应该将Select()更改为SelectMany()。这正是你想要的。

但这不是您案件的最佳解决方案。执行GroupBy().SelectMany()完全没有意义,因为这些操作会相互抵消!

var listClass1 = context.Table1
    .Join(context.Table2,
        t1 => t1.Id,
        t2 => t2.Table1Id,
        (t1, t2) => new { t1, t2 })
    .Where(/*some expressions here*/)
    .Select(x => new Class1
        {
            prop1 = x.t1.Column1,
            prop2 = x.t2.Column2,
            prop3 = x.t1.Column3
        });
从下面的评论中

编辑,我可以看到您正在使用组来获取不同的值(没有完全相等的双行)

可以使用Distinct()方法完成此操作:

var listClass1 = context.Table1
    .Join(context.Table2,
        t1 => t1.Id,
        t2 => t2.Table1Id,
        (t1, t2) => new { t1, t2 })
    .Where(/*some expressions here*/)
    .Distinct() //filters out all the double entries
    .Select(x => new Class1
        {
            prop1 = x.t1.Column1,
            prop2 = x.t2.Column2,
            prop3 = x.t1.Column3
        });

I refer you to this SO question that addresses when to use DISTINCT or GROUP BY.
SQL和LINQ的原理相同,因为LINQ试图模仿SQL的工作方式。

相关问题