【问题标题】:Repository pattern with list as its core in C#C#中以列表为核心的存储库模式
【发布时间】:2015-12-03 20:14:18
【问题描述】:

我正在关注这个网站:http://deviq.com/repository-pattern/

其中有一个使用数据库上下文的存储库模式示例。我正在尝试用一个列表来实现这个通用的 Repository 类(我想要 Repository 类。这是我的要求)。但是,我遇到了 Find 方法的问题。

public class Repository<T> : IRepository<T> where T : class
{
   private List<T> context;

   virtual public T Find(int id)
   {
      // I can't figure out a way to make this work with the list of a generic type
   }
}

这甚至可以在 List.Find() 中仅使用 ID 参数创建谓词吗?我猜不是,但有什么选择?

【问题讨论】:

  • 存储库模式中的上下文是一个 DBContext 对象。不清楚你想做什么。
  • 我认为你需要T: IEntity,其中IEntity 有一个ID。或者你可以使用反射来提取ID
  • 不完全确定我理解这个问题。但是如果 T 实现了一个带有属性 Id 的接口,那么你可以做 Find(p => p.Id == id)
  • 大概你需要知道T 是什么。因为它可以是任何东西,所以你在这里无能为力。您可以将T 限制为比class 更具体的类型,您可以保留abstract 方法,派生的存储库可以实现它,或者您可以完全省略Find(),使用代码可以添加自己的过滤器子句。
  • @user441521:你可以,尽管这样做往往表明存在设计问题。

标签: c#


【解决方案1】:

如果您无法控制 T 的类型以应用接口,则另一种选择是强制您的实现者进行艰苦的工作。

public abstract class Repository<T> : IRepository<T> where T : class
{
   private List<T> context;

   public virtual public T Find(int id)
   {
       return context.FirstOrDefault(x => GetId(x) == id);
   }
   public abstract int GetId(T entity);
}

一个示例实现可能是

// entity
public class Stooge
{
   public Stooges MoronInQuestion {get;set;}
   public double MoeEnragementFactor {get;set;}
   public void PloinkEyes() { /*snip*/ }
   public void Slap() { /*snip*/ }
   public void Punch() { /*snip*/ }
   // etc
}

// enum for an Id? It's not that crazy, sometimes
public enum Stooges
{
    Moe = 1,
    Larry = 2,
    Curly = 3,
    Shemp = 4,
    Joe = 5,
    /* nobody likes Joe DeRita */
    //CurlyJoe = -1, 
}

// implementation
public class StoogeRepository : IRepository<Stooge>
{
    public override int GetId(Stooge entity)
    {
        if(entity == null)
            throw new WOOWOOWOOException();
        return (int)entity.MoronInQuestion;
    }
}

【讨论】:

【解决方案2】:

你可以声明 T 有一个像这样的 Id 属性:

public interface IEntity
{
    int Id { get; }
}

public class Repository<T> : IRepository<T> where T : class, IEntity
{
    private List<T> context;

    virtual public T Find(int id)
    {
        return context.SingleOrDefault(p => p.Id == id);
    }
}

【讨论】:

  • 有趣。因此,我假设我也需要 T 来实现 IEntity 对吗?
  • 是的,您需要一个通用接口。不幸的是,我们没有在 C# 中输入鸭子
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-08
  • 1970-01-01
  • 2018-06-03
  • 1970-01-01
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多