具有动态分组依据的 LINQ

Posted

技术标签:

【中文标题】具有动态分组依据的 LINQ【英文标题】:LINQ with dynamic group by 【发布时间】:2021-04-30 00:49:55 【问题描述】:

我有模特:

public class Student
                
    public string Name get; set;   
    public DateTime BirthDate get; set;         
    public string UniversityName get; set;   
    public decimal Balance get; set;         

我有三个bool 变量:

IsName IsBirthDate IsUniversityName

基于它们,我需要创建GroupBy。如果IsBirthDate=true 那么

DbContext.Students.GroupBy(x => new  x.BirthDate ).Select(s => new
        
            s.Key.BirthDate,                
            Balance = s.Sum(x => x.Balance).ToString(),                
        );

如果IsBirthdate=true, IsUniversityName=true 那么

DbContext.Students.GroupBy(x => new  x.BirthDate, x.UniversityName ).Select(s => new
        
            s.Key.BirthDate,
            s.Key.UniversityName,                
            Balance = s.Sum(x => x.Balance).ToString(),                
        );

以及其他带有布尔参数的选项。

如何使用.GroupBy and .Select动态生成查询?

【问题讨论】:

您可以将它们存储在变量中,然后在if 语句中再次过滤它们。 你不能轻易做到,因为两个GroupBy使用不同的键对象,Select产生不同的对象。两个结果不能放在同一个“类型”的变量中,两个中间结果(GroupBy)也不能 确实,除了实体和聚合字段之外,这两个查询之间几乎没有共同点。如果不通过强制转换为 IEnumerable 删除所有类型信息,您甚至无法从同一函数返回结果 【参考方案1】:

也许这对您有帮助:创建一个代表 GroupBy 的键的类:

public class StudentGroupingKey
                
    public string Name  get; set;   
    public DateTime? BirthDate get; set;         
    public string UniversityName  get; set; 

如果IsName 为真,则分组键的Name 属性将是值,否则它应该始终具有相同的值(例如null)。在您的Select 方法中,您必须始终拥有每个属性,但如果相应的属性为假,它们将为空。如果您需要这些属性不存在,则不能使用匿名类型。在这种情况下,dynamic 可能是一个选择。

DbContext.Students.GroupBy(x => new StudentGroupingKey

    Name = IsName ? x.Name : null,
    BirthDate = IsBirthDate ? x.Birthdate : null,
    UniversityName = IsUniversityName ? x.UniversityName : null
).Select(s => new

   s.Key.BirthDate,
   s.Key.Name,
   s.Key.UniversityName,
   Balance = s.Sum(x => x.Balance).ToString()
);

【讨论】:

不错的方法,谢谢。如何处理匿名类型? @Robert 取出类型名StudentGroupingKey 另外需要写BirthDate = IsBirthDate ? x.Birthdate : (DateTime?) null, @SomeBody 我不需要每个属性,如果对应的属性为假,请建议怎么做? @Robert 如果您不需要这些属性,请忽略它们。无法从匿名类型中删除属性,请参阅***.com/questions/14365858/…

以上是关于具有动态分组依据的 LINQ的主要内容,如果未能解决你的问题,请参考以下文章

具有内部联接、多个分组依据和最小最大值的 Linq 查询

LINQ:结合加入和分组依据

LINQ C# 中的条件计数分组依据

LINQ TO DataSet:数据表上的多个分组依据

如何在 Dynamic Linq Core 中无任何分组

具有分组依据的 PostgreSQL 聚合函数