3

Nous avons une table Personnes qui stocke différents types de personnes (acheteur, vendeur, agent, etc.). Notre ORM est Entity Framework CodeFirst (CTP5). Nous utilisons le modèle de référentiel pour un bon TDD et moqueur. Dans le PersonRepository je veux retourner un type spécifique afin que je puisse faire des choses comme ceci:Generics and Entity Framework: Comment retourner un type différent en fonction d'une valeur de colonne

Agent a = repository.Get<Agent>(5005); // Where 5005 is just an example Id for the person 
a.SomeAgentProperty = someValue; 
Buyer b = repository.Get<Buyer>(253); // Again, a simple PersonId. 
b.SomeBuyerProperty = someOtherValue; 

L'idée est que je sais quel genre de personne que je reçois quand je reçois du référentiel. Et, oui, je pourrais juste créer X différentes méthodes Get appelées GetBuyer (int PersonId), GetSeller (int PersonId) et ainsi de suite. Mais cela a une odeur de code.

À quoi ressemblerait la fonction générique?

Voici mon interface de dépôt jusqu'à présent:

public interface IPersonRepository 
{ 
    Person Get(int PersonId); // To get a generic person 
    T Get<T>(int PersonId);  // To get a specific type of person (buyer, agent, etc.) 
    void Save(Person person); 
    void Delete(int p); 
} 

Et ma mise en œuvre concrète:

public T Get<T>(int PersonId) 
    { 
     //Here's my question: What goes here? 
    } 

Répondre

1

je suggère d'utiliser quelque chose comme:

public T Get<T>(int PersonId) where T: new() 
{ 
    return new T(PersonId); 
} 

et les données de charge en le constructeur ou implémenter une sorte de méthode de chargement pour chaque type de votre entité, comme:

interface IEntity 
{ 
    void Load(int Id); 
} 

class CBuyer: IEntity 
{ 
    public Load(int Id) { ... } 
} 

public T Get<T>(int PersonId) where T: IEntity, new() 
{ 
    T ent = new T(); 
    ent.Load(PersonId); 
    return ent; 
}  
+0

Je voudrais pouvoir voir le code de charge, comment obtient-il le contexte? –

3

utiliser la méthode OfType<T>(), ce qui se traduira par EF faire une jointure interne à la T spécifié si vous utilisez TPT, ou un filtre sur la base du discriminateur si vous utilisez TPH.

public TPerson Get<TPerson>(int PersonId) where TPerson : Person 
{ 
    return ctx.People 
       .OfType<TPerson>() 
       .SingleOrDefault(x => x.PersonId == PersonId); 
} 

Et cela fonctionnera comme vous vouliez:

Agent a = repository.Get<Agent>(5005); 
Questions connexes