C# 使用lambda对多个列进行分组

C# 使用lambda对多个列进行分组,c#,.net,entity-framework,lambda,C#,.net,Entity Framework,Lambda,如何使用lambda对多个列进行分组 我看到了如何使用LINQtoEntities执行此操作的示例,但我正在寻找lambda表单。如果您的表是这样的话 var query = source.GroupBy(x => new { x.Column1, x.Column2 }); rowId col1 col2 col3 col4 1 a e 12 2 2 b f 4

如何使用lambda对多个列进行分组


我看到了如何使用LINQtoEntities执行此操作的示例,但我正在寻找lambda表单。

如果您的表是这样的话

var query = source.GroupBy(x => new { x.Column1, x.Column2 });
rowId     col1    col2    col3    col4
 1          a       e       12       2
 2          b       f       42       5
 3          a       e       32       2
 4          b       f       44       5


var grouped = myTable.AsEnumerable().GroupBy(r=> new {pp1 =  r.Field<int>("col1"), pp2 = r.Field<int>("col2")});
rowId col1 col2 col3 col4
1 a e 12 2
2 b f 42 5
3 a e 32 2
4 b f 44 5
var grouped=myTable.AsEnumerable().GroupBy(r=>new{pp1=r.Field(“col1”),pp2=r.Field(“col2”)});
进一步回答上述问题-如果需要根据这些分组键进行筛选,则可以定义一个类来包装多个键

return customers.GroupBy(a => new CustomerGroupingKey(a.Country, a.Gender))
                .Where(a => a.Key.Country == "Ireland" && a.Key.Gender == "M")
                .SelectMany(a => a)
                .ToList();
其中CustomerGroupingKey接受组键:

    private class CustomerGroupingKey
    {
        public CustomerGroupingKey(string country, string gender)
        {
            Country = country;
            Gender = gender;
        }

        public string Country { get; }

        public string Gender { get; }
    }
类元素
{
上市公司;
公共字符串类型的投资;
公众价值;
}
班级计划
{
静态void Main(字符串[]参数)
{
列表元素=新列表()
{
新元素{Company=“JPMORGAN CHASE”,typeof investment=“Stocks”,Worth=96983},
新元素{Company=“AMER TOWER CORP”,typeof investment=“Securities”,Worth=17141},
新元素{Company=“ORACLE CORP”,typeof investment=“Assets”,Worth=59372},
新元素{Company=“PEPSICO INC”,typeof investment=“Assets”,Worth=26516},
新元素{Company=“PROCTER&GAMBL”,TypeOfInvestment=“Stocks”,Worth=387050},
新元素{Company=“QuaslCom INC”,投资类型=“债券”,价值=196811},
新元素{Company=“UTD TECHS CORP”,typeof investment=“Bonds”,value=257429},
新元素{Company=“WELLS FARGO-new”,投资类型=“银行账户”,价值=106600},
新元素{Company=“FEDEX CORP”,typeof investment=“Stocks”,Worth=103955},
新元素{Company=“CVS CAREMARK CP”,typeof investment=“Securities”,Worth=171048},
};
//LINQ(查询方法)中多列的分组依据
var query=来自元素中的e
e组通过新的{e.typeof investment,e.Company}进入eg
选择新{eg.Key.TypeOfInvestment,eg.Key.Company,Points=eg.Sum(rl=>rl.Worth)};
foreach(查询中的var项)
{
Console.WriteLine(item.TypeOfInvestment.PadRight(20)+“+item.Points.ToString());
}
//LINQ中多列的分组方式(Lambda方法)
var CompanyDetails=elements.GroupBy(s=>new{s.Company,s.TypeOfInvestment})
.选择(g=>
新的
{
公司=g.Key.company,
投资类型=g.Key.Typeof投资,
Balance=g.Sum(x=>Math.Round(Convert.ToDecimal(x.Worth),2)),
}
);
foreach(公司详细信息中的var项目)
{
Console.WriteLine(item.TypeOfInvestment.PadRight(20)+“+item.Balance.ToString());
}
Console.ReadLine();
}
}

我提出了一种混合定义类的方法,就像David的答案一样,但不需要使用Where类。它看起来像:

var resultsGroupings = resultsRecords.GroupBy(r => new { r.IdObj1, r.IdObj2, r.IdObj3})
                                    .Select(r => new ResultGrouping {
                                        IdObj1= r.Key.IdObj1,
                                        IdObj2= r.Key.IdObj2,
                                        IdObj3= r.Key.IdObj3,
                                        Results = r.ToArray(),
                                        Count = r.Count()
                                    });



private class ResultGrouping
        {
            public short IdObj1{ get; set; }
            public short IdObj2{ get; set; }
            public int IdObj3{ get; set; }

            public ResultCsvImport[] Results { get; set; }
            public int Count { get; set; }
        }

其中,
resultRecords
是我要分组的初始列表,它是一个
列表
。注意,这里的想法是,我通过3列进行分组,IdObj1、IdObj2和IdObj3

这真的有效吗?我认为对每个分组对象的相等性测试都会失败,因为它们是对象而不是结构。@Aducci:谢谢。您能举例说明如何获取组项的IEnumerable吗?@Jacob-匿名类型是不可变的类,具有正确重写的
GetHashCode
&
Equals
方法。它们正是为这种用例而设计的。@Naor-
GroupBy
返回一个
IEnumerable
,它本质上是一个
IEnumerable
,在内部枚举表上有一个
属性。这是否有助于您获取组项的“IEnumerable”?
new{}
关键字似乎是
new
C#实体的金锤,做得不错。可能会节省一些时间:最好使用对象初始值设定器的默认构造。上面示例代码中的方法不会被像EF Core这样的ORM很好地处理。需要注意的是,AsEnumerable会在分组之前将整个表放入内存中。这在某些桌子上肯定很重要。有关更多信息,请参见此答案:
var resultsGroupings = resultsRecords.GroupBy(r => new { r.IdObj1, r.IdObj2, r.IdObj3})
                                    .Select(r => new ResultGrouping {
                                        IdObj1= r.Key.IdObj1,
                                        IdObj2= r.Key.IdObj2,
                                        IdObj3= r.Key.IdObj3,
                                        Results = r.ToArray(),
                                        Count = r.Count()
                                    });



private class ResultGrouping
        {
            public short IdObj1{ get; set; }
            public short IdObj2{ get; set; }
            public int IdObj3{ get; set; }

            public ResultCsvImport[] Results { get; set; }
            public int Count { get; set; }
        }