简体   繁体   English

实体框架通用存储库的规范模式

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM