2010-04-09 4 views
1

Je me demandais simplement s'il existait un moyen de prendre une partie de la répétition d'un type projeté LINQ to SQL.LinqToSql: Comment créer une projection pour adhérer à DRY?

Exemple:

Tableau: Adresse

Domaines: AddressID, HouseNumber, Rue, Ville, État, Zip, +20 plus

Classe MyAddress: AddressID, HouseNumber , Rue (seulement 3 champs)

LINQ:

 
from a in db.Addresses 
select new MyAddress 
{ 
    AddressID = a.AddressID, 
    HouseNumber = a.HouseNumber, 
    Street = a.Street 
} 

La requête ci-dessus fonctionne parfaitement, et je comprends pourquoi quelque chose comme cela renverra tous les champs 20+ dans chaque ligne:

 
from a in db.Addresses 
select new MyAddress(a); 

class MyAddress 
{ 
    public MyAddress(Address a) 
    { 
    this.AddressID = a.AddressID, 
    this.HouseNumber = a.HouseNumber, 
    this.Street = a.Street 
    } 
} 

Ce qui me conduit à ma question:

Est Est-il possible d'implémenter une sorte de fonction d'aide ou une méthode d'extension pour "mapper" du modèle LINQ à MyAddress mais seulement retourner les champs nécessaires dans le résultat de la requête plutôt que tous les champs?

+0

Pourquoi avez-vous besoin d'un type de données réduit pour commencer? –

+0

Si je travaille avec une table qui a 20-30-40 champs et que j'ai seulement besoin de/want 3, pourquoi SQL fait-il le travail et renvoie toutes ces données supplémentaires sur le fil? – Mike

Répondre

2
from a in db.Addresses 
select new MyAddress 
{ 
    AddressID = a.AddressID, 
    HouseNumber = a.HouseNumber, 
    Street = a.Street 
} 

Cette requête sélectionne uniquement les champs requis dans le SQL résultant.

Une fonction de réutiliser le type ressemblera:

public IQueryable<MyAddress> ProjectAddress(IQueryable<Address> addresses) 
{ 
    return from a in addresses 
      select new MyAddress 
      { 
       AddressID = a.AddressID, 
       HouseNumber = a.HouseNumber, 
       Street = a.Street 
      }; 
} 

Ceci peut être utilisé comme ceci:

return ProjectAddress(db.Addresses); 

Je pense que la fonction ressemblerait à quelque chose comme:

public static Expression<Func<Address, MyAddress>> ToMyAddress() 
{ 
    return a => new MyAddress { AddressID = a.AddressID, 
           HouseNumber = a.HouseNumber, 
           Street = a.Street 
           }; 
} 
+0

Il semble que la clé est IQueryable comme type de retour? Que diriez-vous d'une seule adresse? J'ai un objet qui a deux propriétés: OriginalAddress et CurrentAddress, les deux de type adresse. Est-il possible de créer une fonction d'assistance pour accepter le "modèle de domaine" et cracher un "modèle de vue", tout ce que j'essaie finit par tirer l'ensemble de l'enregistrement de la base de données. Est-ce que je tente de refactoriser trop? – Mike

+0

L'utilisation de IQueryable signifie que linq restera une expression sur laquelle s'appuyer, qui sera ensuite résolue en requête et exécutée. Je pense que je comprends ce que vous essayez d'accomplir: représenter la projection de l'entité d'adresse dans le modèle de vue d'adresse en tant que code, et l'utiliser comme un appel de fonction plusieurs fois dans une autre projection. Est-ce correct? – SteadyEddi

+0

La clé sera d'utiliser linq dynamique et de créer une expression qui représente la transformation. À mon humble avis je dirais que le code résultant semblera assez compliqué à quiconque n'est pas familier avec la construction d'expressions et la métaprogrammation. Il va certainement augmenter la valeur DRY bien. Je ferais un jugement et je dirais si je répète le code dans un nombre significatif d'endroits, et que changer ce code prendra beaucoup de temps, alors allez-y. – SteadyEddi