我使用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;
}
}
“类别”是一个复杂的类,看起来像这样:
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()
}))
这样做很好,但我想知道是否有可能以某种方式改善其性能。
问题1:我认为,可能一个查询的效果会好于四个。是否可以将这些查询合并为一个查询?
第二季度:当我要求Linq按“行业”分组时,究竟能够区分一个行业到另一个行业?它隐含地比较记录的密钥吗?如果我明确告诉linq要分组哪个属性(例如“id”)会不会更快?谢谢!
答案 0 :(得分:0)
按相反顺序回答:
Q2:
当您按对象而不是基类型进行分组时,它使用标准相等比较器(obj x == obj y)进行简单的引用比较(http://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx)。如果适合,它可以工作,否则你可以实现自定义相等比较器(How to implement IEqualityComparer to return distinct values?)
Q1:
如果您想要组的子组,则可以在单个查询中执行此操作。如果你只想要每个人的计数,那么你就是以正确的方式做到了。
答案 1 :(得分:0)
您可以使用条件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()
};