How-to implement Specification Pattern with Entity Framework ?
相关问题
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- Why am I getting UnauthorizedAccessException on th
- 求获取指定qq 资料的方法
- How to know full paths to DLL's from .csproj f
Basically, there should be nothing special (due to EF) when implementing the specification pattern. You implement the specifications as separate classes, which work with your domain model.
You can find lots of articles or webcasts about the specification pattern, and even some which use EF, e.g. here and here.
As probably you already know, the specification pattern will enable you to send a filter to your repository (among other usages). I have seen many implementations to do that.
Usually, people expose another method on the specification interface representing the expression tree that has to be sent to Entity Framework:
The repository will call the
GetPredicate
method and pass it to theWhere
method on EF´s DbSet. That way you have restricted which expressions will be generated, and guarantee that it´ll generate a valid SQL statement.To enable the boolean operators on the specification, you´ll need to mix expressions together. there is this post from Vladmir Khorikov where he explains in detail how to do that.
I usually dont like this solution, since it assumes your domain model is the same as your persistence model. Most people are ok with that. But I like to keep things VERY separated on a Onion architecture.
I found by experience that eventually Entity Framework will pollute your domain model with dbcontexts, EF attributes, public setters, properties that only make sense on the database, etc.
So I usually keep 2 separate models (classes), with the "persistence" entity one being very simple and very similar to the database schema, and a "domain" entity enriched with behavior and invariants.
And that poses a problem to the solution above, because the specification lives on the domain model, and cannot have dependencies for the persistence model.
So you´ll need to navigate the specification composite and create to create a predicate. the Visitor is a good design pattern for that.
I recently wrote a series of posts where I explain
Specification Pattern:
For those who want a primer, visit this link.
Understand Specification for Entity Framework:
Read this. This covers the following very important points. In any sort of real world application you will quickly want to chain multiple specifications together. This is referred to as composing specifications. You will need to gain a grasp of some of the caveats for the resolution of specification composition within Linq to Entities. You need to know this because using Linq to Entities is the desirable approach to expressing specification satisfaction criteria.
Fix the Badness:
Download and install this. It fixes the shortcoming of Linq to Entities that you read about in step two. This explains more detail of the fix's implementation.
Implement It!
You should have enough information to implement the pattern. Keep googling. Doing this for EF is not entirely simple but well worth the effort. This is a very interesting implementation.
Just use NSpecifications lib. It's free. You can use it with any ORM based on IQueryable interface such as Entity Framework or Linq2Sql: https://github.com/jnicolau/NSpecifications
Or get it from Nuget:
Install-Package NSpecifications -Version 1.1.0