Repository design pattern

岁酱吖の 提交于 2019-11-27 06:54:42

问题


I have seen many repository pattern implementations. Specifically of 2 types

  1. They expose the generic repository which is queryable and expects a lamba expression from service class to get data from database.

  2. Write methods to get the data from database based on business requirements and encapsulate the logic (even lambda) of retrieving the data.

Which one is a better approach?


回答1:


I really prefer the second one.

Even I've seen articles from top bloggers on .NET world, queryables, for me, are evil in a repository.

Reasons:

  1. A repository is like a collection of objects but stored wherever its implementation has defined.

  2. A repository abstracts the way data is mapped to object. Data store could be whatever, but business relies on repository in order to retrieve, add, update or remove domain objects.

  3. Any read or write access to the underlying store must be managed by the repository itself - or any other underlying layer -.

Queryable destroys most of these points and/or reasons.

For example, why you would design a GetProductByName, GetProductByCode, if you can do it with LINQ on IQueryable?

And Queryable works bad in n-tier scenarios, since you won't be having access to the database connection in another tier than the one which returned a deferred set.

I don't think "queryable" concept and repository should be good for any software design, because it's telling that repository is useless.

Queryable is like designing a GetAll method. What's the point of a GetAll in a repository? Repository will be retrieving all domain objects and you'll be filtering them in business. But... Wait... Repository isn't supposed to retrieve domain objects with some criteria, is it?

Although I find queryable incompatible with repository, designing and implementing some repository method that accepts a lambda expression or any delegate in order to give some kind of filter or behavior, for me, is fine. This isn't deferred execution, it's delegation.




回答2:


I prefer the first one.

The queryable version is better because it requires less code and is more flexible.

You don't have to know in advance what you are looking for.

  // instead of repository.FindByMinimumAge(18)
  customerList = repository.Find<Customer>(c => c.Age >= 18)

With the second approach your Repository-Interface must contain a Method FindByMinimumAge(int minimumAge) (and a methodFindByName and a method ....)

update

The repository interface looks like this.

public interface IRepository<T> where T : class
{
    IEnumerable<T> Find(Expression<Func<T, bool>> where);
    ...
}

This can be implemented ie by NHibernate, Linq2Sql or "Mock using an arraylist".



来源:https://stackoverflow.com/questions/5166888/repository-design-pattern

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!