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

时间:2010-10-22 03:24:06

标签: c# repository-pattern

我是知识库的新手。我刚刚阅读了有关实现谓词和工作单元(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);
}

当然,工作单元会将数据上下文(Microsoft粉丝)注入新的存储库,其中工作单元将具有.Save()方法,在所有数据上下文中调用Save。

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

这是对的吗?漏?我错过了什么? OrderBy的方法是否不必存在于存储库中? Paging(.Skip()。Take())应该以某种方式在谓词中实现吗?

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

2 个答案:

答案 0 :(得分:5)

如果您引用的是实体框架 我建议你读这个: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>

2,保持我的代码干燥。 一些实体可能有自己的数据操作方法。 (即商店程序) 您可以轻松扩展它而无需触及其他存储库。

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

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

有一段时间,保持代码清晰和逻辑可读对于更好的应用程序结构也很重要。

答案 1 :(得分:2)

您提供的存储库界面是一个非常易于使用的CRUD界面,可以在许多类型的应用程序中很好地工作。一般来说,我宁愿在我的存储库中没有分页和排序参数或选项,而是我宁愿返回一个IQueryable,让调用者将这些类型的操作组成查询(只要你是IQueryable,像EF一样的技术或者nHibernate可以将这些运算符转换为SQL - 如果你回退到IList或IEnumerable,那就是内存操作。

虽然我避免分页和排序,但我可能在存储库上有更多特定的操作来保护业务逻辑不受某些细节的影响。例如,我可能会从IRepository扩展IEmployeeRepository并添加一个GetManagers方法或类似的东西来隐藏查询中所需的Where表达式。这一切都取决于应用程序和复杂程度。

你帖子中关于这句话的一个重要说明:

  

当然,工作单位会   注入数据上下文(微软粉丝)   到新的存储库,单位   of Work会有一个.Save()方法,   在所有数据上下文中调用Save。

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

我在这个项目中有几个示例实现: http://odetocode.com/downloads/employeetimecards.zip

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

希望有所帮助,