我们有一个人员表,存储不同类型的人(买方,卖方,代理等)。我们的ORM是实体框架CodeFirst(CTP5)。我们正在使用存储库模式进行良好的TDD和模拟。在PersonRepository中我想返回一个特定的类型,所以我可以做这样的事情:
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;
我的想法是,当我从存储库中获取它时,我知道我正在获得什么样的人。并且,是的,我可以创建X个不同的Get方法,称为GetBuyer(int PersonId),GetSeller(int PersonId)等等。但那有代码味道。
泛型函数看起来如何?
到目前为止,这是我的存储库界面:
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);
}
我的具体实施:
public T Get<T>(int PersonId)
{
//Here's my question: What goes here?
}
答案 0 :(得分:3)
使用OfType<T>()
方法,如果您使用TPT,将导致EF对指定的T进行INNER JOIN,或者如果您使用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);
答案 1 :(得分:1)
我建议使用类似的东西:
public T Get<T>(int PersonId) where T: new()
{
return new T(PersonId);
}
并在构造函数中加载数据或为您的每个实体类型实现某种Load方法,例如:
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;
}