2009-11-19 5 views
3

Je voulais juste vérifier s'il existe une manière plus élégante d'accomplir cette tâche en utilisant Linq. Je simplifie grandement le code pour plus de brièveté. Je vais dans mes motifs dans une minute, mais il va comme ceci:Linq Combine Fields

(from t in doc.Descendants(p + "Task") 
where t.Element(p + "Name") != null 
select new { 
    FirstName = t.FirstName, 
    LastName = t.LastName, 
    FullName = FirstName + " " + LastName // Error! 
} 

Oui, je sais que ce serait simple FullName = t.FirstName + « » + t.LastName, mais imaginons pour une seconde que FirstName et LastName étaient de gros calculs en ligne laids et pas de simples variables. Donc FullName = [gros calcul laid 1] + [grand laid calc 2]. Donc, dans l'esprit de DRY, y a-t-il une meilleure façon de faire cela? Ma première pensée est d'écrire une fonction qui me donne FirstName et LastName. Mais y a-t-il quelque chose de mieux?

Répondre

8

Eh bien, vous pouvez faire:

from t in doc.Descendants(p + "Task") 
where t.Element(p + "Name") != null 
let FirstName = t.FirstName 
let LastName = t.LastName 
select new { FirstName, LastName, Fullname = FirstName + LastName } 

Il sera légèrement inefficace en termes des projections que ça va passer, mais ça va marcher.

serait légèrement plus efficace être:

from t in doc.Descendants(p + "Task") 
where t.Element(p + "Name") != null 
select new { t.FirstName, t.LastName } into x 
select new { x.FirstName, x.LastName, FullName = x.FirstName + x.LastName } 
+1

Bah, me battre pour elle. Avez-vous ces questions quelques minutes devant nous? :) –

+0

@Winston - Ouais semble toujours m'arriver! –

+0

Sweet! Je vous remercie. – billb

2

Si vous ne faites pas un type anonyme, vous pouvez tout simplement pas préciser le FullName du tout et l'ont défini comme un champ calculé.

Exemple:

class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string FullName { get { return FirstName + " " + LastName; } } 
} 

puis l'utiliser dans votre déclaration LINQ:

(from t in doc.Descendants(p + "Task") 
where t.Element(p + "Name") != null 
select new Person { 
    FirstName = t.FirstName, 
    LastName = t.LastName 
} 
2

Vous pouvez faire

public void SomeClassMethod() 
{ 
    List<Person> people = new List<Person>(); 

    people.Add(new Person() { FirstName = "Bob", Surname = "Smith" }); 
    people.Add(new Person() { FirstName = "Sally", Surname = "Jones" }); 

    var results = 
     from p in people 
     let name = p.FirstName + " " + p.Surname 
     select new 
     { 
      FirstName = p.FirstName, 
      Surname = p.Surname, 
      FullName = name 
     }; 
} 

public class Person 
{ 
    public String FirstName { get; set; } 
    public String Surname { get; set; } 
}