代码之家  ›  专栏  ›  技术社区  ›  Zachary Scott

Repository模式:如何在C#中实现包含谓词的基本存储库?

  •  1
  • Zachary Scott  · 技术社区  · 14 年前

    我是新来的仓库。我刚读到关于实现谓词和工作单元的内容(Fowler)。我见过如下存储库界面:

    public interface IRepository<ET> {
        ET        Add( ET entity);
        ET        Remove( int id);
        ET        Get( int id);
        IList<ET> Get(Expression<Func<T, bool>> predicate);
    }
    

    没有编辑方法,所以我假设您可以修改从存储库中弹出的任何实体,然后调用工作单元上的save changes。

    这是对的吗?漏水?我错过了什么?OrderBy方法不需要放在存储库中吗?是否应该在谓词中以某种方式实现分页(.Skip().Take())?

    链接到示例代码会非常棒,尤其是如何在存储库中实现谓词。

    2 回复  |  直到 14 年前
        1
  •  5
  •   D.J    14 年前

    如果您指的是实体框架 我建议你读一下: http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx

    我不是知识库模式的专家,但是我现在在项目中使用它。一个零件形式的性能,以下是我从这个设计模式中发现的好处:

    1、简化所有实体的CRUD操作实现。

    public interface IDataRepository<T> where T : class
    

    然后你就能很容易很快地复制其他的

    public class EntityOneRepository : IDataRepository<EntityOne>
    public class EntityTwoRepository : IDataRepository<EntityTwo>
    

    有些实体可能有自己的数据操作方法。(即存储过程) 您可以轻松地扩展它,而不必接触其他存储库。

    public interface IDonationRepository : IDataRepository<Donation>
    {
    //method one
    //method two
    //....
    }
    

    对于分页,可以通过Skip()和take()完成,也可以在数据库中定义自己的SP,然后通过EF4调用它。在这种情况下,您还将受益于数据库sp缓存。

        2
  •  2
  •   OdeToCode    14 年前

    您介绍的存储库接口是一个非常易于使用的CRUD接口,可以在许多类型的应用程序中很好地工作。一般来说,我不希望在我的存储库中有分页和排序参数或选项,而是希望返回一个IQueryable并让调用者将这些类型的操作组合到查询中(只要您是IQueryable,像EF或nHibernate这样的技术就可以将这些运算符转换为SQL—如果您回到IList或IEnumerable,它是所有内存操作)。

    尽管我避免分页和排序,但我可能在存储库上有更具体的操作来屏蔽业务逻辑的某些细节。例如,我可以从IRepository扩展IEmployeeRepository并添加GetManagers方法,或者类似的方法来隐藏查询中所需的Where表达式。这完全取决于应用程序和复杂程度。

    在你的文章中有一个重要的注意事项:

    插入数据上下文(Microsoft fan) 到新的仓库,在那里 会有一个.Save()方法, 对所有数据上下文调用Save。

    确保在每个工作单元中使用单个数据上下文/对象上下文,因为上下文本质上是底层工作单元。如果您在同一个逻辑事务中使用多个上下文,那么您将有效地拥有多个工作单元。

    http://odetocode.com/downloads/employeetimecards.zip

    如果您阅读随附的这篇文章,代码可能更有意义: http://msdn.microsoft.com/en-us/library/ff714955.aspx