当存在类似于以下内容的对象时,如何使用LINQ基于Id运行GroupBy:
public class foo
{
public int id { get; set; }
public string name { get; set; }
public string lang { get; set; }
public int displayOrder { get; set; }
public int count { get; set; }
}
列表可能是:
id = 1, name="test1", lang = "en", displayOrder = 1, count = 1
id = 1, name="test2", lang = "fr", displayOrder = 2, count = 2
id = 1, name="test3", lang = "de", displayOrder = 3, count = 1
id = 2, name="test4", lang = "en", displayOrder = 2, count = 1
id = 2, name="test5", lang = "fr", displayOrder = 3, count = 1
id = 3, name="test6", lang = "en", displayOrder = 6, count = 1
id = 3, name="test7", lang = "fr", displayOrder = 4, count = 1
id = 4, name="test8", lang = "en", displayOrder = 5, count = 1
id = 5, name="test9", lang = "de", displayOrder = 6, count = 1
我想运行LINQ以使其按分组依据值,但应根据lang过滤不同的id值,例如: “fr”,如果“fr”中没有任何内容,它应该只输出“en”的默认语言记录 但是还应该根据Id计算记录总数,它应该检索上面的以下结果:
id = 1, name="test2", lang = "fr", displayOrder = 2, count = 4
id = 2, name="test5", lang = "fr", displayOrder = 3, count = 2
id = 3, name="test7", lang = "fr", displayOrder = 4, count = 2
id = 4, name="test8", lang = "en", displayOrder = 5, count = 1
id = 5, name="test9", lang = "de", displayOrder = 6, count = 1
拜托,有没有办法用LINQ做这样的事情? 你们所有的LINQ专家,我理想地使用lambda寻找查询,这将是一个很大的帮助。提前谢谢。
答案 0 :(得分:2)
您可以将目标语言排在前面,然后选择组中的第一项:
var query = from f in foos
group f by f.id into g
let lang = (from f in g
orderby
f.lang == "fr" ? 0 : 1,
f.lang == "en" ? 0 : 1,
f.lang
select f).First()
select new
{
id = g.Key,
lang.name,
lang.lang,
lang.displayOrder,
count = g.Sum(f => f.count)
};
这假设对(id,lang)是唯一的。
答案 1 :(得分:0)
这可能会稍快一些,因为它不需要遍历组中的所有项目进行订购。
var res = data
.GroupBy(d => d.id)
.Select(g => new {
id = g.Key,
count = g.Sum(d => d.count),
Lang = g.FirstOrDefault(d => d.lang == "fr") ?? g.First()
})
.Select(g => new {
g.id,
g.Lang.lang,
g.Lang.name,
g.Lang.displayOrder,
g.count
})
.ToList();