After almost 11 months of design, development, beta testing and adding final polish, it's here: LLBLGen Pro v2.6! This version, which is a free upgrade for all our v2.x customers, has a couple of major new features, the biggest of course being the full implementation of Linq support in our O/R mapper framework. The work on our Linq provider, which we've dubbed 'Linq to LLBLGen Pro', lasted almost 9 months and was discussed on this blog in a series of articles, which I'll linq () to below.
In the beginning of writing the Linq provider, I was pretty optimistic that it would be easy and quick, but after a while I got very pessimistic and wanted to skip it entirely as it would simply cost too much effort, and therefore time and money. The main reason was the lack of serious documentation and background on various essential details like which expression trees were formed from which linq queries, and how to understand them in full so a meaningful query could be produced from them to run on the database. Anyone who has written some form of Linq provider or is currently busy doing so will run into this problem. Doing trial-error development/research for a couple of months in a row isn't a picknick, but it's also part of being a Software Engineer so it always left me with a mixed bag of what to think of it: it's exciting and interesting, but also frustrating.
A good example of the lack of serious documentation on expression trees is the way the VB.NET compiler compiles a group-by query into an expression tree vs. how the C# compiler does that: the C# compiler always adds a separate .Select() method call, the VB.NET compiler doesn't. In theory, the VB.NET compiler is right: the group-by clause has to be in the same query scope as the projection, but as C# has to be supported as well, you have to build some form of 'look-ahead' inside the tree to see when / if / how the projection is present after the group-by expression is seen. This isn't documented anywhere. Another one is the way how anonymous types are detected. There's no boolean on the Type object which tells you 'This is an anonymous type'. So you check the name. The C# compiler generates names which start with <>, the VB.NET compiler generates names which start with $VB$. And probably yet another language which runs on the CLR and which adds Linq support might choose another prefix. Nowhere is this documented but it is sometimes required to know that the type you're dealing with is an anonymous type.
But that's all water under the bridge now. Looking back, I'm so incredibly happy that management did succeed in motivating me to go on and continue working on the Linq provider, as the end result is one of the most feature-rich Linq providers available on .NET today. With the future technology coming from Microsoft like Dynamic Data and ADO.NET Data services, but also with IQueryable supporting controls from third-party developers like DevExpress, it's becoming more and more clear that a modern O/R mapper system has to have deep and solid Linq support.
I won't enlist everything here, just a few items of what's new in LLBLGen Pro v2.6.
- Full Linq support with our own Linq to LLBLGen Pro provider.
- .NET 3.5 support. With code changes in the runtime so it works better with Linq to Objects and with VS.NET 2008 project templates
- Derived table support. Use any query as source for a join side or as From clause
- Much lower memory consumption during transactions: 90% less memory overhead for temp values during transactions. Temp values are used to be able to roll-back to the start state of the entity graph when a transaction rolls back (PK's roll back, FK's synced with the new PK values roll back etc.)
- Up to 20% less memory usage for entity graphs
- String uniquing. When fetching a lot of redundant string data, the same string instance is now re-used to avoid unnecessary memory consumption. This is done without string interning.
- SqlServer 2008 support, SqlServer CE 3.5 support, CF.NET 3.5 support
- Using SqlServer CE Desktop is now much easier
- Plus... a lot of small, but important changes and enhancements.
Linq to LLBLGen Pro development articles
For the people who want to re-read all the articles on the development of Linq to LLBLGen Pro, they're linked below.
- Developing Linq to LLBLGen Pro, part 0
- Developing Linq to LLBLGen Pro, part 1
- Developing Linq to LLBLGen Pro, part 2
- Developing Linq to LLBLGen Pro, part 3
- Developing Linq to LLBLGen Pro, part 4
- Developing Linq to LLBLGen Pro, part 5
- Developing Linq to LLBLGen Pro, part 6
- Developing Linq to LLBLGen Pro, part 7
- Developing Linq to LLBLGen Pro, part 8
- Developing Linq to LLBLGen Pro, part 9
- Developing Linq to LLBLGen Pro, part 10
- Developing Linq to LLBLGen Pro, part 11
- Developing Linq to LLBLGen Pro, part 12
- Developing Linq to LLBLGen Pro, part 13
- Developing Linq to LLBLGen Pro, part 14
Hereby, I'd like to thank all the beta-testers and all the others who have supported us and have given feedback in one way or the other! .
In the next weeks we'll be releasing updated code for our Dynamic Data support and also new code for support for ADO.NET Data Services (Astoria). We'll also publish our Linq to Sql templates on our main site so people who aren't yet a customer can try them out as well.
The coming year
In the coming year, we'll be working on LLBLGen Pro v3, something I'm very excited about. It won't just be a designer upgrade, it will be a designer revolution, combined with a new way of generating code. Of course, we'll be bringing further enhancements and fine-grained tweaks to our own O/R mapper framework and runtime. The project goals are huge, but that's what makes things interesting, right? One of the first steps is a transactional graph manager which can manipulate object graphs in-memory on a transactional basis. I hope to blog about that sometime soon.
But for now, a day of rest and sunshine .