【问题标题】:Another Q about Linq grouping关于 Linq 分组的另一个问题
【发布时间】:2025-11-28 03:45:02
【问题描述】:

我使用 Linq(连同 EF)来访问我的数据库。我有对象“Job”,它包含几个属性,其中一些是“复杂的”。我的目标是按这些属性对作业进行分组,并对每个组进行计数。

这是我的对象(简化):

public class Job
{
    [Key]
    public int Id
    {
        get;
        set;
    }


    [Required]
    public Salary Salary
    {
        get;
        set;
    }


    [Required]
    public ICollection<Category> Categories
    {
        get;
        set;
    }     
}

“Category”是一个复杂的类,看起来像这样:

public class Category
{
    [Key]
    public int Id
    {
        get;
        set;
    }

    public Industry Industry //Example: Software
    {
        get;
        set;
    }


    public Field Field //Example: .NET
    {
        get;
        set;
    }


    public Position Position //Example: Developer
    {
        get;
        set;
    }
}

Industry、Field、Position 和 Salary 类仅包含“int”id 和“string”名称。

我需要按行业、领域、职位和薪水对工作列表进行分组,并计算每个组的数量。这就是我现在的做法:

var IndustryGroupsQuery = from t in Jobs.SelectMany(p => p.Categories)
                                          group t by new { t.Industry} into g
                                          select new 
                                          { 
                                              Tag = g.Key.Industry,
                                              Count = g.Count()
                                          };

var FieldsGroupsQuery = from t in Jobs.SelectMany(p => p.Categories)
                                          group t by new { t.Field} into g
                                          select new 
                                          { 
                                              Tag = g.Key.Field,
                                              Count = g.Count()
                                          };

var PositionsGroupsQuery = from t in Jobs.SelectMany(p => p.Categories)
                                          group t by new { t.Position} into g
                                          select new 
                                          { 
                                              Tag = g.Key.Position,
                                              Count = g.Count()
                                          };

Jobs.GroupBy(job => job.Salary)
                       .Select(group => new
                       {
                           Tag = group.Key,
                           Count = group.Count()
                       }))

这很好用,但我想知道是否有可能以某种方式提高它的性能。

Q1:我认为,一个查询可能会比四个查询执行得更好。是否可以将这些查询合并为一个查询?

Q2:当我要求 Linq 按“行业”分组时,它究竟如何区分一个行业和另一个行业?是否隐式比较记录的键?如果我明确告诉 linq 要按哪个属性分组(例如“id”)会更快吗?

谢谢!

【问题讨论】:

    标签: c# sql linq


    【解决方案1】:

    以相反的顺序回答:

    第二季度:
    当您按对象而不是基类型分组时,它使用标准相等比较器 (obj x == obj y),它执行简单的引用比较 (http://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx)。如果适合,它可以工作,否则您可以实现自定义相等比较器 (How to implement IEqualityComparer to return distinct values?)

    第一季度:
    如果您想要组的子组,那么您可以在单个查询中完成。如果您只想要每个的计数,那么您的做法正是正确的。

    【讨论】:

    • 如果查询在数据库上运行,它如何通过引用进行比较?
    【解决方案2】:

    您可以使用条件GROUP BY

    您可以定义一个变量来告诉查询使用哪一列进行分组。您可以为 GROUP BY 列定义一个 ENUM。

     int groupByCol = 1; //Change the value of this field according to the field you want to group by
    
     var GenericGroupsQuery = from t in Jobs                                          
                                 group t by new { GroupCol = ( groupByCol == 1 ? t.Industry:(groupByCol == 2 ? t.Field:(groupByCol == 3 ? t.Position : t.Job)))} into g
                                 select new 
                                 { 
                                    Tag = g.Key,
                                    Count = g.Count()
                                 };
    

    【讨论】: