Pages

Monday, December 10, 2012

Code Review Corner Part 1

Ever wonder what's going on inside Entity Framework development?

Well, now you can because Entity Framework is open source!

But who really has the time to read through an insanely lengthy codebase.

Wouldn't it be great to just see a few gems from their codebase and maybe a few not-so-gems?  

Personally, I'd love to be able to go to an opensource project and get overview of exactly what 3rd party libraries they're using, how many dlls they have and what test coverage their tests have.

I'd even just like to know some of their coding standards and what they think makes good code.

I am going to try and deliver these things in this next series of blog posts.  

If you'd like me to review a codebase, email me your recommendation or comment below.  

I swear I won't scold people for not using hungarian notation.

I'll leave off with an interesting tidbit before I actually do review the entity framework.  Did you know Microsoft globally suppresses their own rule 

CA1502: Avoid excessive complexity



Heck, were you aware of GlobalSuppression.cs?

We're going to learn a lot.

Saturday, January 21, 2012

LINQ Tips : Writing D.R.Y. LINQ

What good is LINQ to entities if you have to write your C# logic and then repeat it in another place as "will become SQL" logic?  Having to update the same logic in multiple places to add a feature to your codebase is highly undesirable; so much so that it even has a name.

Luckily, the ADO.NET team  asked the same question and, in this post, we'll make sure you're writing LINQ to Entities code as unlike inline SQL as possible and try to break our query down into reusable pieces.

Let's consider a simple scenario : 

You have a book store management website.  On one page, you're displaying every single book that has a genre.  Then, on another page, you're displaying every single book and adding a button  next to the record to add a genre if there isn't one.

Here's our data model
Here's what you shouldn't do :



It looks innocent enough, but why must our logic for determining whether a book has a genre or not be baked into our .Where call?  Is this really the best we can do?  How can we combine that logic with other queries that also check if a book lacks a genre.

Here's what you should do :


And our helper method looks like this.  








This was all done so that we could do this in our view (The second place we need to execute this logic--only this time we need to actually extract the Func<Book, bool> by compiling it into CIL.  The way we do this is by calling Compile() which will recurse through our expression tree and produce the actual CIL we want--we then simply invoke it.

We should have written another wrapper for this invoke call to make another nice helper, but I don't want to drown the reader in screenshots.

(The model is a list of Book)

At this point we should be ecstatic!  We've managed to keep the logic of determining an empty genre outside of the view entirely!   And we've already "composed" our Books() method with the BookHasNoGenre method to accomplish a single task.

Here's the page fully rendered :







Conclusion

Hopefully, you've been convinced that it's a good idea to avoid repeating yourself and that you CAN, in fact, write D.R.Y. LINQ to entities code that isn't just inline SQL in disguise.

I will post the code if anyone requests it.