【问题标题】:Generics and Entity Framework: How do I return a different type depending on a column value泛型和实体框架:如何根据列值返回不同的类型
【发布时间】:2011-01-22 06:06:26
【问题描述】:

我们有一个 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?
    }

【问题讨论】:

    标签: c# entity-framework generics repository-pattern entity-framework-ctp5


    【解决方案1】:

    使用OfType&lt;T&gt;() 方法,如果您使用 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);
    

    【讨论】:

      【解决方案2】:

      我建议使用类似的东西:

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

      【讨论】:

      • 我希望我能看到 Load 的代码,它是如何获取 Context 的?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多