2010-10-14 32 views
5

Étant donné deux classes dans votre fichier .dbml LINQ to SQL avec les propriétés suivantes.encapsulation logique dans une requête linq à sql via la méthode d'extension

Customer 
    CustomerId 
    FirstName 
    LastName 
    AddressId 

Address 
    AddressId 
    Street 
    City 
    State 
    Zip 

Vous pouvez construire une requête LINQ comme celle-ci. Maintenant, disons que vous vouliez excapsuler la logique pour assembler l'adresse postale. Deux façons que vous pourriez accomplir cela serait d'ajouter une nouvelle propriété à la classe Customer, ou créer une méthode d'extension.

public static class CustomerExtensions 
{ 
    public static string GetMailingAddress(this Customer cust) 
    { 
     return cust.FirstName + " " 
        + cust.LastName 
        + Environment.NewLine 
        + cust.Address.Street 
        + Environment.NewLine 
        + cust.Address.City + ", " 
        + cust.Address.State + " " 
        + cust.Address.Zip; 
    } 
} 

public partial class Customer 
{ 
    public string MailingAddress 
    { 
     get 
     { 
      return this.FirstName + " " 
        + this.LastName 
        + Environment.NewLine 
        + this.Address.Street 
        + Environment.NewLine 
        + this.Address.City + ", " 
        + this.Address.State + " " 
        + this.Address.Zip; 
     } 
    } 
} 

vous pouvez maintenant utiliser l'un de ceux-ci et vous obtiendrez des résultats corrects

using(var db = new MyDataContext()) 
{ 
    results = db.Customers 
     .Where(c => c.LastName.BeginsWith("o")) 
     .Select(c => new 
      { 
       c.CustomerId, 
       c.MailingAddress, //new property 
       Address2 = c.GetMailingAddress() // new extension method 
      }).ToList(); 

} 

Le problème avec ces deux façons est que cela pourrait entraîner une là pour être un aller-retour supplémentaire à la base de données pour chaque ligne que vous récupérez. La requête initiale retirera les informations de la table Customer, puis elle devra gradualiser individuellement chaque enregistrement d'adresse lorsqu'il évaluera l'adresse postale.

Existe-t-il un moyen d'encapsuler cette logique et de la lier à la classe de clients de telle sorte que vous n'ayez pas besoin d'aller plus loin dans la base de données?

Je pense qu'il doit y avoir un moyen de créer une méthode d'extension qui renvoie à la place une expression au lieu d'une chaîne. Ai-je raison? Si oui, comment ferais-je cela?

Répondre

3

Je sais que ce n'est pas exactement ce que vous cherchez, mais vous pouvez le faire:

var options = new DataLoadOptions(); 
options.LoadWith<Customer>(c => c.Address); 
db.LoadOptions = options; 

Ensuite, il ne fera que faire un voyage que l'adresse est récupérée avec le client.

+0

Merci Richard, ça marche mais vous avez raison, ce n'est pas tout à fait ce que j'espère trouver pour deux raisons. Tout d'abord, la méthode d'appel doit alors savoir quelque chose sur ce qui est impliqué dans la construction de 'MailingAddress', c'est-à-dire qu'elle nécessite la table d'adresses. Deuxièmement, disons que la table d'adresses contenait en réalité beaucoup plus de 5 champs, je crois que faire cela ramènerait beaucoup plus de données que ce dont nous avons réellement besoin. – eoldre