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;
}
精彩评论