[英]Specification pattern with Entity Framework generic repository
Recently I have encountered an article Implement the Query Specification pattern and I am confused about using specification pattern with generic repository.最近我遇到了一篇实现查询规范模式的文章,我对将规范模式与通用存储库一起使用感到困惑。
I have already a generic repo like this:我已经有一个像这样的通用回购:
public interface IGenericRepository<T> where T:class
{
IReadOnlyList<T> GetAllAsunc(int id);
IReadOnlyList<T> FindAsync(Expression<Func<T, bool>> filter);
T GetById(int id)
void Add(T item);
void Update(T item);
void Delete(T item);
}
And a sample method for specification pattern以及规范模式的示例方法
public BaseSpecification(Expression<Func<T, bool>> criteria)
{
Criteria = criteria;
}
I can send any expression with IReadOnlyList<T> FindAsync(Expression<Func<T, bool>> filter);
我可以使用
IReadOnlyList<T> FindAsync(Expression<Func<T, bool>> filter);
发送任何表达式method.方法。 So, I don't really understand why I need specification pattern with generic repository.
所以,我真的不明白为什么我需要带有通用存储库的规范模式。 It looks they are doing same things.
看起来他们在做同样的事情。 Could you clarify this?
你能澄清一下吗?
The specification pattern covers more than just a filter expression, it also covers eager loading and pagination.规范模式不仅涵盖过滤器表达式,还涵盖了预加载和分页。 In your example, if you were dealing with an entity that referenced 3 other entities and had a child collection, how would you tell your repository method which of those should be eager loaded?
在您的示例中,如果您正在处理一个引用了其他 3 个实体并有一个子集合的实体,您将如何告诉您的存储库方法应该预先加载其中哪些? If your List method could return hundreds of thousands of rows, how would you tell it to load just a page of 50 at a time?
如果您的 List 方法可以返回数十万行,您将如何告诉它一次只加载 50 页?
In my personal opinion, using the Specification is a SRP band-aid on a generic repository.在我个人看来,使用规范是通用存储库上的 SRP 创可贴。 Generic repositories are an anti-pattern in EF systems where you are positioning your repository code to have a great number of "forces" lobbying for change using the Specification to mitigate that.
通用存储库是 EF 系统中的一种反模式,您将存储库代码定位为拥有大量“力量”游说更改使用规范来缓解这种情况。 I would never advocate for trying to build an MVC web application with a single generic
Controller<T>
implementation, and for the same reason I don't advocate using Repository<T>
.我永远不会提倡尝试使用单个通用
Controller<T>
实现来构建 MVC web 应用程序,出于同样的原因,我不提倡使用Repository<T>
。 Specifications do not protect callers from being polluted with domain / EF knowledge because every expression passed in must conform to the rules set out by the domain implementation.规范并不能保护调用者免受域/EF 知识的污染,因为传入的每个表达式都必须符合域实现制定的规则。 While a specification might handle filtering, eager loading, and pagination... What about sorting, projection, or other aggregate functions like exist checks and counts?
虽然规范可能会处理过滤、急切加载和分页......排序、投影或其他聚合函数(如存在检查和计数)呢? At the end of the day it's a complexity rabbit hole trying to satisfy SOLID principles making your code considerably more complex and harder to follow, and slamming head-first into barriers repeatedly as new requirements don't conform to past assumptions.
归根结底,这是一个复杂的兔子洞,试图满足 SOLID 原则,使您的代码变得更加复杂和难以遵循,并且由于新的要求不符合过去的假设而反复冲撞障碍。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.