Some observations on Linq to Sql & Entity Framework codebases
So, I have to do a lot of L2S and EF work recently, while trying to create L2SProf and EFProf. The interesting tidbit is that I got a totally different approach to using them than almost anyone else.
I don’t really care for either as an OR/M (I have my own, thank you very much), I only care for plugging into them deeply enough that I can get the information that I want.
With L2S, that was fairly easy, all I needed to do was figure out how to get access to the logging that it was already doing, and I was pretty much done. With EF, there isn’t any logging, and I was left having to write my own EF provider (and then plugging that in). I am going to talk about how I plugged myself into EF at some length some other time.
One of the most frustrating things with L2S is while the initial implementation was significantly easier than EF, it doesn’t take very long to hit a hard wall of internal stuff. What is worse, it is pretty obvious that there was some pretty sweet architecture inside that got totally killed for non technical reasons. Sometimes, I feel like a code archeologist. I mean, take a look at SqlProvider.Initialize() in reflector for a second:
I am willing to bet that this stuff was added after the decision to kill the L2S provider model was added. This kind of stuff really need to be in a separate provider, but that would have forced IProvider to be public, so it was hacked around.
With the EF version, there are absolutely no visibility into what EF is doing (by that I mean logging, tracing, etc). It does have extensibility in it, however, which means that I could plug into that and then replace enough things until I had the hooks in place to provide the information that I needed. This isn’t that much fun, I’ll admit, but it is working for me so far.
The initial leap to get EF profiling working is much harder, but once that is done, it is pretty straightforward to get most of the stuff that I need. L2S basic architecture make the first few steps very easy, but then you get into a maze of blocked internal stuff.
The more I work on this, the more I like this blog’s tagline.
Comments
i wander what caused microsoft to (seemingly) build EF from scratch and with a radically different architecture. L2S couldn't possibly have been that bad. In fact they deliberately threw out lazy loading which is ... ah ... not so smart. I say deliberately because they could have implemented a slim version in a few hours by adding into the codegen "if(!Loaded) Load() return innerCollection;". This is the exact code one has to write manually now.
It is interesting that they are adding the features of L2S to EF.
That code came from the original team, as was the provider interface being private.
Even with it private SqlCE support still could have been written as a separate provider without IProvider being public so the argument doesn't hold.
What likely happened is somebody thought the SqlCE stuff would be a few relatively simple switches but it grew and grew and it looks like it never got refactored into it's own mechanism.
[)amien
@tobi - The story goes that L2S was being developed by the C# team at the same time that EF was being developed by the Data Programability team. Neither team knew what the other was doing and there was quite a surprise.
Oren, would you need to register a DbProviderFactory for the EFProf?
@Julie: thats entirely plausible to me. would not have been the first time that two teams are doing the same thing at microsoft. looks like the c# team knew what they were doing a little better.
Dmitry,
No, EF Prof is completely non invasive.
I'm a big fan of L2S and use it at work, mainly because of its simplicity and because it's a much easier sell to a team that isn't chalk full of uber coders than some other ORM tools. Anyone with any OO and ADO.NET experience in .NET can ramp up with L2S and understand what it's doing without much time investment. It also plays nice with vanilla ADOO.NET and existing SqlTransactions.
However, you're right - it does have some pretty big limitations, of which the 3 biggest in my opinion are that it's SQL Server only, it's one class per table only, and it's difficult to know how to build a more formal DAL without running into issues with the DataContext object's convoluted lifecycle. But for many small dev shops, those limitations aren't such a big deal and are outweighed by the RAD L2S provides.
That said, I think you make an interesting point about L2S architecture, and how some of its limitations aren't technical, but are due to MS strategically crippling it for use with other providers. But it's also interesting that regardless of what MS allows with it, L2S has shown what is possible, and that there's a huge untapped market for an easy to use tool like L2S to wean people off of DataTables.
I think that the popularity of L2S also shows that there was a missed opportunity for Castle's ActiveRecord to get itself out there more. AR has a huge advantage in that it's still NHibernate under the covers, but it's not very well known and doesn't seem to have the momentum that L2S has. Maybe the MS blessing made L2S what it is, but I'd still like to see AR develop as somewhat of a gateway drug to get NHibernate in the door in some of these smaller shops. That's the disconnect that MS will struggle to overcome as it tries to convince people to go from L2S to EF which are two totally different tools. And that's a huge advantage that AR+NHibernate have over L2S+EF, if only someone would notice the opportunity.
Hey Ayende, probaby a bit late now for you but a coleague of mine wrote an article on how to do DI with LINQ to SQL, so you can make it a bit provider based.
You can find it here - www.codeproject.com/KB/linq/LinqAndUnity2.aspx (I did chastise him for using CodeProject though :P)
Comment preview