Reputation: 11143
How-to implement Specification Pattern with Entity Framework ?
Upvotes: 17
Views: 18538
Reputation: 106
Just use NSpecifications lib (that I wrote myself). 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
Upvotes: 1
Reputation: 2303
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:
public interface ISpecification<T>
{
bool IsSpecifiedBy(T item);
Expression<Func<T, bool>> GetPredicate()
}
The repository will call the GetPredicate
method and pass it to the Where
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
Upvotes: 0
Reputation: 96541
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.
Upvotes: 4