Generics and Entity Framework: how to return a different type depending on the value of a column

We have a table of persons in which different types of persons are stored (buyer, seller, agent, etc.). Our ORM is Entity Framework CodeFirst (CTP5). We use the repository template for good TDD and mockingly. In PersonRepository, I want to return a specific type so that I can do things like this:

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;

The idea is that I know what kind of person I get when I get it from the repository. And, yes, I could just create X different Get methods called GetBuyer (int PersonId), GetSeller (int PersonId) and so on. But it has a smell of code.

What will the general function look like?

Here is my repository interface:

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

And my specific implementation:

    public T Get<T>(int PersonId)
    {
        //Here my question: What goes here?
    }
+3
source
2

- :

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

- , :

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

OfType<T>(), , EF INNER JOIN T, TPT , TPH.

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

, :

Agent a = repository.Get<Agent>(5005);
+3

Source: https://habr.com/ru/post/1787089/


All Articles