Generics and Entity Framework: How do I return a different type depending on a column value

风格不统一 提交于 2019-12-06 06:43:44

问题


We have a Persons table which stores different types of persons (Buyer, Seller, Agent, etc). Our ORM is Entity Framework CodeFirst (CTP5). We're using the repository pattern for good TDD and mocking. In the PersonRepository I want to return a specific type so 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'm getting 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 that has a code smell.

How would the generic function look?

Here is my repository interface so far:

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 concrete implementation:

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

回答1:


I would suggest to use something like:

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

and load data in the constructor or implement some kind of Load method for each type of your entity, like:

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



回答2:


Use the OfType<T>() method, which will result in EF doing an INNER JOIN to the specified T if your using TPT, or a filter based on the discriminator if your using TPH.

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

And that will work just like you wanted:

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


来源:https://stackoverflow.com/questions/4766450/generics-and-entity-framework-how-do-i-return-a-different-type-depending-on-a-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!