开发者

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

We have a Persons table which stores different types of persons (Buyer, Seller, Agent, etc). Our ORM is Entity Fra开发者_StackOverflow社区mework 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?
    }


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


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜