Tuesday, August 20, 2013

Homemade Lightweight Automapper Part 1

I've been using MVC3.NET for just over a year now in a project for work. I find myself liking the approach, I feel more in control of the code that I write, and while I admire MS efforts, I am glad to be rid of the horrible overhead that is the ViewState.

Using Entity Framework, I've learned a *lot* about linq. I went with a POCO approach for my models. I feel that this approach is much more elegant and lightweight than relying on EF to map everything out, and the less auto-generated nightmarish code the better IMHO.

If there is one thing I could complain about MS's bash at the MVC paradigm, it is how code heavy it is. Classes and classes and more classes. And did I mention classes? Once you get used to the slightly over engineered verboseness of it though, you do begin to appreciate the perks that go with it.

In the project I'm currently working on, we decided early on to start work with the Kendo JS framework, which is pretty shiny, and to try and help reduce code a bit, we started using the AutoMapper 3rd party library fairly early on.

Well, if you've used Kendo, you'll know that for the MVC side of things, all of the 'big' data display controls such as grids or lists are designed fairly heavily around taking their data in IQueryable format. They will take any IEnumerable, but if you have more than a few hundred records being pulled from your database, you don't want to materialize those records into memory until you need to, or things get slooooooooowwww very quickly.

Let me back up and give a brief outline of Entity Framework and Linq. There are two kinds of linq that use the same syntax and both work on most any sort of container object... arrays, dictionaries, lists, etc. Linq to Object works on objects in memory, Linq to SQL works specifically in a monadic way to generate a SQL query that is only run at the last minute.

You generally use L2SQL on IQueryables and L2OBJ on everything else. Problems arise when casting IQueryables to their parent interface IEnumerables because then you can quickly lose track of where your data is and run into performance issues (among other things).

After jumping into the deep end (When I started on this project, I personally had *very* little MVC experience no Kendo experience, no linq or Entity Framework experience and had been working in .NET 2.0 until that time) we quickly discovered that Sorting, Grouping, and Paging, the main 3 things you want to do with data in a Grid, did not play nicely unless you were working with IQueryables... oh they work fine if you only have a few hundred records, but once your DB starts filling up, a few thousand records being sorted, paged and grouped in memory rather than at the DB hurts really badly.

The AutoMapper had worked reasonably well up until that point but there was one hitch: It did not work with IQueryables. I did a bit of research and discovered that it indeed worked with IQueryables if you used a certain syntax... something along the lines of Project().To(), but the line of code would always inexplicably crash, no matter how much I coaxed it. Pretty sure that the particular version of the library that we were using had a bug, and unfortunately at the time it was not an option to upgrade.

This lead me to start looking into ways I could simply do it myself. After all, the Automapper code is fairly ugly to work with anyway, albeit fairly powerful if you work it right. I'll use the next 1-2 blog posts to run through how to create a rudimentary automapper that works fairly well in most complex cases.

No comments:

Post a Comment