3

我们有一个存储不同类型人员(买方,卖方,代理等)的人员表。我们的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? 
    } 

回答

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

我希望能看到加载代码,它是如何获得的语境? – 2013-02-22 02:34:40

3

使用OfType<T>()方法,这将导致EF做的,如果你使用TPT,或过滤器基于鉴别,如果您使用的TPH INNER JOIN到指定的T。

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