Linq Lambda从聚合中获取两个属性作为字符串

时间:2012-11-15 15:25:50

标签: c# linq lambda aggregate anonymous-class

在对匿名选择的linq查询中,我想从两个属性连接字符串。

例如,找到某些人群中最老的人的全名。

var personsAndOldest = db.Persons.GroupBy(person => person.SomeThingThatCanBeGroupedForPerson).Select(a => new
            {
                FirstName = a.FirstOrDefault().FirstName,
                LastName = a.FirstOrDefault().LastName,
                BirthDate = a.FirstOrDefault().BirthDate,
                FullnameOfOldes = a.Aggregate((pers1, pers2) => pers1.BirthDate > pers2.BirthDate ? pers1 : pers2).FirstName + " " //How do I get LastName of the old one (without using the full aggregate again)
            });

我是否必须再次编写完整聚合以获取firstname和whitespace之后的LastName?

3 个答案:

答案 0 :(得分:1)

你可以这样做

var personsAndOldest = db.Persons
    .GroupBy(person => person.SomeThingThatCanBeGroupedForPerson)
    .Select(g => new 
        {
            a = g.First(),
            o = g.Aggregate((pers1, pers2) =>
                pers1.BirthDate > pers2.BirthDate ? pers1 : pers2)
        })
    .Select(pair => new
        {
            FirstName = pair.a.FirstName,
            LastName = pair.a.LastName,
            BirthDate = pair.a.BirthDate,
            FullnameOfOldes = pair.o.FirstName + " " + pair.o.LastName
        });

答案 1 :(得分:1)

您可以在Select:

中使用lambda语句
var personsAndOldest = db.Persons.GroupBy(person => person.SomeThingThatCanBeGroupedForPerson).Select(a => 
    {
        var first = a.First();
        var oldest = a.Aggregate((pers1, pers2) => pers1.BirthDate > pers2.BirthDate ? pers1 : pers2);
        return new
        {
            FirstName = first.FirstName,
            LastName = first.LastName,
            BirthDate = first.BirthDate,
            FullnameOfOldes = oldest.FirstName + " " + oldest.LastName)
        };
    });

答案 2 :(得分:0)

  • 您可以使用let来引入新的范围变量。
  • 如果匿名类型的属性名称等于已分配属性的名称
  • ,则无需为其指定属性名称
  • 我认为OrderBy会找到最老的人(但你可以使用聚合并比较表现)
  • 我认为最老的人是出生日期最短的人,因此您需要将汇总更改为pers1.BirthDate < pers2.BirthDate ? pers1 : pers2

所以

var personsAndOldest = from p in db.Persons
                       group p by p.SomeThingThatCanBeGroupedForPerson into g
                       let first = g.FirtOrDefault()
                       let oldest = g.OrderBy(x => x.BirthDate).FirstOrefault()
                       select
                       {
                           first.FirstName,
                           first.LastName,
                           first.BirthDate,
                           FullnameOfOldes = oldest.FirstName + " " + oldest.LastName
                       };