2012-11-15 15 views
5

All'interno di una query linq su anonimo selezionare Voglio concatenare stringhe da due proprietà.Linq Lambda ottiene due proprietà come stringa dall'aggressione

Ad esempio per trovare il nome completo della persona più anziana in un gruppo di persone.

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) 
      }); 

Devo scrivere nuovamente l'aggregazione completa per ottenere il cognome dopo il nome e lo spazio bianco?

+0

Vuoi ogni risultato di avere il pieno nome della persona più anziana o si desidera che solo la persona più anziana abbia popolato 'FullnameOfOldes'? – davisoa

risposta

1

Si potrebbe utilizzare una dichiarazione lambda nella Selezione:

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) 
     }; 
    }); 
1

È possibile farlo come

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 
     }); 
0
  • È possibile utilizzare let per introdurre nuove variabili gamma.
  • Non è necessario specificare nome della proprietà per il tipo anonimo se è uguale a nome della proprietà assegnato
  • Penso OrderBy troverà persona più anziana (ma è possibile utilizzare aggregare e confrontare le prestazioni)
  • credo che persona più anziana è uno con il minimo data di nascita, quindi è necessario cambiare l'aggregazione di pers1.BirthDate < pers2.BirthDate ? pers1 : pers2

così

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 
         }; 
+1

Huh, non ci avevo pensato fino a quando non ho letto il tuo terzo proiettile, ma questo uso di "Aggregate" sembra un'alternativa praticabile a "MaxBy" di MoreLINQ o "O (n log n)" OrderBy (...) .Prima() '. – Rawling

+1

@Rawling grazie mille per aver menzionato 'morelinq'! È molto interessante dare un'occhiata alle loro implementazioni –