3

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

2 回答 2

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);
于 2011-01-22T06:17:12.630 回答
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;
}    
于 2011-01-22T06:15:04.000 回答