Reusing predicates in EntityFramework
Warning: some knowledge of Expressions is required.
Entity Framework simplifies a great number of things; for starters, I don't have to write a lot of SQL which makes development a lot faster - I'm a lot more productive in C# than SQL. One thing that works really well in EF, is the ability to reuse predicates - how often do you find yourself typing:
In progamming we often get taught to DRY out the code - i.e. Don't Repeat Yourself. I think that extends to the expressions we're pass in to EF. The expressions are the specification language of EF (ignore that part if you don't do DDD). I'll look at a couple of ways of storing that expression - first up: extension methods.
and a context:
Now we're ready to start playing with those extension methods.
That makes it super easy to dry out the code:
As long as you have the correct using statements you'll even get great intellisense support. It's also easy to extend by chaining calls:
That' all non deleted posts by "Bar" containing the text "Foo". It's a compelling pattern and has worked really well. I still use this for my projections e.g. ProjectToBlogPostWithComments();.
Now, this doesn't look very different at all - and actually, at this point there is absolutely no compelling reason to favour the expressions over the extension methods. The real power comes when you start combining the filters into a single expression and only calling Where once.
You'll have to ignore the magic "And" method for now - that's what I'm going to talk about in the next blog post.
Combining the expressions into a single expression produces less nested SQL and results in zero duplication of predicates. The extension methods (or multiple wheres) result in the earlier predicates being repeated multiple times. As the expression approach doesn't it has cut the cost of some queries I have tested by more than 33%.
In the next post I'll talk about the And() method and it's sibling the Or() method.
Entity Framework simplifies a great number of things; for starters, I don't have to write a lot of SQL which makes development a lot faster - I'm a lot more productive in C# than SQL. One thing that works really well in EF, is the ability to reuse predicates - how often do you find yourself typing:
In progamming we often get taught to DRY out the code - i.e. Don't Repeat Yourself. I think that extends to the expressions we're pass in to EF. The expressions are the specification language of EF (ignore that part if you don't do DDD). I'll look at a couple of ways of storing that expression - first up: extension methods.
Set up
Let's a assume we have a blog post entity like:
Now we're ready to start playing with those extension methods.
Extension methods
The simplest, and the approach that I first used, is to create an extension method:That makes it super easy to dry out the code:
As long as you have the correct using statements you'll even get great intellisense support. It's also easy to extend by chaining calls:
That' all non deleted posts by "Bar" containing the text "Foo". It's a compelling pattern and has worked really well. I still use this for my projections e.g. ProjectToBlogPostWithComments();.
Expression fields and factories
Using expressions looks like this:Now, this doesn't look very different at all - and actually, at this point there is absolutely no compelling reason to favour the expressions over the extension methods. The real power comes when you start combining the filters into a single expression and only calling Where once.
You'll have to ignore the magic "And" method for now - that's what I'm going to talk about in the next blog post.
Combining the expressions into a single expression produces less nested SQL and results in zero duplication of predicates. The extension methods (or multiple wheres) result in the earlier predicates being repeated multiple times. As the expression approach doesn't it has cut the cost of some queries I have tested by more than 33%.
In the next post I'll talk about the And() method and it's sibling the Or() method.
Comments
Post a Comment