考虑以下简化对象和关系:
public class Job{
int JobId;
String name;
String status;
Discipline disc;
WorkCategory workCat;
}
public class Discipline {
int DisciplineId;
String DisciplineName;
}
public class Workcategory{
int WorkCategoryId;
String WorkCategoryName;
}
public Class Grouping{
Discipline parent;
List<Workcategory> children;
}
以上模拟了Job
与一个Discipline
和一个WorkCategory
相关联的关系。 Workcategory
始终是特定父级Discipline
的子级(一对多关系)。我们可以假设指定的Discipline和Workcategory的关系始终有效。
我面临的问题是,当我尝试根据应用于Grouping
的过滤器创建Jobs
结果对象时。我不确定如果可以做到这一点,或者我采取的方法是否正确。确切的问题本身并不清楚,但上面定义了问题陈述。
Grouping
课程?我尝试了以下(这是我第一次尝试使用Linq),但没有成功,因为我的理解不够完整。另一种方法是首先获取Discipline
组并循环完成原始分组,然后选择相关的Workcategory
。
var grouping = repository.GetJobsWithActiveStatus()
.GroupBy(x => new {
x.Discipline.DisciplineID,
x.Discipline.DisciplineName,
x.Category.WorkCategoryID,
x.Category.WorkCategoryName
})
.Select(g => new Grouping{
Discipline = new Discipline{
DisciplineID = g.Key.DisciplineID,
Name = g.Key.DisciplineName
},
Categories = ?? // this is where I am lost
}});
编辑: 在发布之后,我意识到初始GroupBy参数导致一组项目,而我正在寻找Group-SubGroup结果。
编辑2:
为了进一步澄清,我不希望关联的Jobs作为结果的一部分,而是将Discipline-Workcategory分组 - 因此Grouping
类的原因
基于@Obalix的初始解决方案
编辑2010年3月7日:
此解决方案不起作用 - 对象Discipline上的GroupBy将为每个对象生成唯一的分组。我认为这是因为它是一种参考类型。我对么? 我最初接受这个作为答案,但是经过一些头脑的抓挠后发现我的模拟数据本身就是错误的。最初的问题仍然存在。
var result = repository.GetJobsWithActiveStatus()
.GroupBy(x => x.disc)
.Select(g => new Grouping
{
Discipline = g.Key,
Catergories = g.GroupBy(x=>x.workCat) // <--- The Problem is here, grouping on a reference type
.Select(l=>l.Key) // needed to select the Key's only
.ToList()
});
答案 0 :(得分:2)
Here is a description如何实现分层分组机制。
使用LINQ(如链接中所示)执行此操作的一般方法是:
var list = new List<Job>();
var groupedList = list.GroupBy(x => x.disc)
.Select(g => new {
Key = g.Key,
Count = g.Count(),
WorkCategoryGroups = g.GroupBy(x => x.workCat)
});
但是,该链接还描述了一种允许您执行以下操作的替代方法:
var groupedList = list.GroupByMany(x => x.disc, x => x.workCat);
编辑:以下艾哈迈德的评论是强类型版本:
var groupedList = list.GroupBy(x => x.disc)
.Select(g => new Grouping {
parent = g.Key,
children = g.GroupBy(x => x.workCat).ToList()
});
答案 1 :(得分:2)
我会使用Linq语法:
var jobsByDiscipline =
from j in repository.GetJobsWithActiveStatus()
group j by j.Discipline.DisciplineID into g
select new {
DisciplineID = g.Key,
Jobs = g.ToList()
};
var jobsByCategory =
from j in repository.GetJobsWithActiveStatus()
group j by j.Workcategory.WorkcategoryID into g
select new {
WorkcategoryID = g.Key,
Jobs = g.ToList()
};
我觉得比使用lambda函数参数的许多链式方法更容易阅读。
您可以从中获取分组:
var disciplineAndCategory =
from j in repository.GetJobsWithActiveStatus()
group j by j.Discipline.DisciplineID into g
let categories =
from j2 in g
select j2.Workcategory.WorkcategoryID
select new {
DisciplineID = g.Key,
Jobs = categories.Distinct() // each category id once
};
答案 2 :(得分:0)
这是另一种不需要分组类的方法。
ILookup<Discipline, Workcategory> result = repository
.GetJobsWithActiveStatus()
.Select(job => new {disc = job.disc, workCat = job.workCat})
.Distinct()
.ToLookup(x => x.disc, x => x.workCat);
答案 3 :(得分:0)
这是适合我的解决方案。
我首先需要获得所有学科组,然后创建相关的工作类别列表 discipID相等的地方。
var result = liveJobs
.GroupBy(x => new {
x.disc.DisciplineID,
x.disc.DisciplineName
})
.Select(g => new Grouping()
{
parent = new Discipline(g.Key.DisciplineID,g.Key.DisciplineName),
children = g.Where(job=>job.disc.DisciplineID == g.Key.DisciplineID) // filter the current job discipline to where the group key disciplines are equal
.Select(j=>j.workCat)
.ToList()
});