Linq is Really Cool -- But DLinq is a Big Mess

I'm not at the PDC since I instead decided that attending an event at Microsoft in Redmond in a few weeks would be the better use of my time and money, but I have been following things closely.  I had heard that System.Query, now named Linq for Lanquage Integrated Query, and the next version of ObjectSpaces, now named DLinq, would be revealed, but I had not been able to get any details.  Well now we have quite a few details, and after reading the blogs and docs and installing Linq/DLinq, and looking under the covers with Reflector, its now quite clear that Linq is really cool -- and DLinq is a big mistake.

First, let me be very clear -- Linq is a very significant improvement in being able to query structures in a strongly typed manner with both intellisense and compile-time checking.  Even better is that it looks like Sql, which is something I've long pushed as being simpler for most people to use than yet another query language, but this is old news to anyone familiar with C-Omega.  But Linq by itself only knows how to work with in-memory structures -- in other words, on its own it doesn't know how to interoperate with your other data stores like relational databases and Xml documents.

So that's where DLinq and XLinq come in -- they are essentially extensions that allow you to use Linq to work with relational databases using DLinq and Xml documents using XLinq.  XLinq seems to be well received so far, although it looks like it expects you to know far too much Xml in my opinion, unlike my open-source XmlDbClient that allows you to use basic Sql with Xml documents.  But DLinq is already getting mixed reviews -- it seems that those that aren't using O/R Mappers think its a big improvement, while those familiar with O/R Mappers, including myself, find it to be the wrong solution.

What's wrong with DLinq?  Here's the list I have so far: attribute-based, MS Sql Server only, overly complicated, poor stored proc support, no server-side paging, very limited functionality, and no WinFS/OPath integration.  I've commented on why attributes are superior to attributes before, and others are already chiming in on this, so I'm simply going to point out that they've failed in delivering their own goal to be "non-intrusive", which is stated in the DLinq docs.  Next, while many people don't care about being able to simultaneously targetting multiple databases, its also very true that many people that target only one database do NOT work with MS Sql Server!

By the way, I've looked under the covers using Reflector, and while it may be theoretically possible that they can remedy this before their eventual release, its also pretty clear that they haven't thought about this.  This might be understandable given that this is an early technology preview if it wasn't the third time that MS has previewed an O/R Mapper and been roundly criticized for not supporting other databases.  Yes, this is the third time -- their was an early version of ObjectSpaces in the original .NET v1.0 preview at the PDC in 2000, and then their was the major rewrite in the early versions of .NET v2.0 -- so this is their third attempt.

I also believe that while Linq is very easy to use, DLinq is needlessly complex because it actually expects you to know a lot more than just ADO.NET and Sql, much like XLinq expects too much Xml knowledge.  Consider their example query "from c in db.Customers where c.City == 'London' select c;" -- note that db.Customers only works because they have elsewhere defined Customers as a Table<Customer> type.  But you've already marked your Customer class with the attribute "Table(Name = 'Customers')", not too mention all the Column attributes -- so why isn't the attribute enough to make it clear what "Customers" refers to?

Similarly, what if all I want to do is to get a list of all my customers -- why should I have to say "from c in db.Customers select c" when I could just "from Customers" or have a strongly typed Get accessor?  My point is that while Linq really is great, you shouldn't be required to write out all of your sql statements for the simple cases after you've gone to all this trouble to mark everything with attributes.  Instead Linq should be reserved as the query language for the cases where you need more, and then the fact that it looks much like Sql will be its strength -- but there is no reason why it should be required for the many common simple cases.

Now I've also seen some question whether there is support for persistence and/or stored procs, but a quick look through the docs make it quite clear that both are supported so that isn't an issue.  That said, for MS pushing stored procs so heavily, they haven't really thought out how to support stored procs very well for persistence -- again this wouldn't be a big issue if this wasn't their third attempt.   So you have to write your own insert, update, and delete methods, mark them with the appropriate attributes, and supply all the logic, including the stored proc name and parameters, in your own code -- not really O/R Mapping as I know it.

And then there are some of the other minor issues which may change as DLinq develops, but again keep in mind that this is NOT a first attempt, so it begs the question of what MS learned from their other attempts -- and all our previous feedback.  There's no server-side paging (nor is there in ADO.NET since that was removed), there's no many-to-many relationship yet, and so far there's no support for inheritance and its not clear if distributed apps have been considered.  Finally, we were told that ObjectSpaces was delayed so it could be synced with WinFS, but I fail to see any integration with WinFS or OPath at all -- so I wonder if anyone is in charge?

Oh one last thing, since I've already been asked this by several people -- should O/R Mapper vendors be scared, and in particular should I be scared about my ORMapper that was based on ObjectSpaces?  If I were to answer this purely from a logical feature-by-feature comparison approach, then the answer is obvious that O/R Mapper vendors have nothing to fear, nor does my own ORMapper.  But the problem in the Microsoft world, unlike the Java and open-source worlds, is that 99% of the developers never use anything except what MS gives them, and while this may give developers a taste of O/R Mappers, its also unfortunately going to leave a very poor taste.

28 Comments

  • &quot;...But you've already marked your Customer class with the attribute &quot;Table(Name = 'Customers')&quot;, not too mention all the Column attributes -- so why isn't the attribute enough to make it clear what &quot;Customers&quot; refers to?&quot;



    Perhaps one might use two databases at once? What's wrong with that?



    About being tied to MS SQL: I don't think that it will be tied to anything at the end (not sure what's the situation right now).



    But look on the bright side: it supports read after save and it supports saving all context at once.



    :-)

  • I think you'll find with a closer look at the docs that even using multiple databases doesn't require that additional complexity. And while I hope you're right that it won't be tied to MS Sql in the end, so far experience has taught us otherwise -- and as others have already pointed out (and me also a long time ago), an attribute based system makes it much harder to support multiple databases in many real-world cases. Finally, who doesn't support read after save, and you already know that I consider saving an entire context to be a questionable practice in most cases, but to each his own.

  • You said:



    why should I have to say &quot;from c in db.Customers select c&quot; when I could just &quot;from Customers&quot; or have a strongly typed Get accessor...



    In actuality, you can do foreach(var c in db.Customers).



    You do not have to use select if you want all the customers. Table&lt;Customer&gt; derives from IEnumerable&lt;Customer&gt;.

  • That's good to know, although in that case it doesn't look like there's any way to define a default sort order that many of us provide.

  • It may not be intended to be a &quot;full&quot; ORM, but it is nonetheless an ORM. My own ORM also does not try to have every feature, but that's because it is targetted at simplicity and the most common 90-95% scenarios -- and I'm stating that DLinq fails in those goals too, and that after years of effort and already having had lots of feedback.



    Now I have read that document and seen that quote, but I believe you're failing to see that anyone attempting to build a &quot;full ORM&quot; on top of DLinq will still be limited by its basics. How will you build something on top of it without first defining these attribute based entities, and how will you add support for other databases if DLinq does not do so?



    No, I'm sorry, but DLinq is an O/R Mapper although it does appear they don't want to call it that -- maybe they're afraid people will then discover there are others once they are familiar with that term. :) And if someone seriously believes its not an ORM, then do tell what it is?

  • Hi Paul,



    &quot;I think you'll find with a closer look at the docs that even using multiple databases doesn't require that additional complexity.&quot;



    But how would you specify from which database you want read from?



    &quot;And while I hope you're right that it won't be tied to MS Sql in the end, so far experience has taught us otherwise &quot;



    Yes and no. Look at ADO.NET for example.





    &quot;-- and as others have already pointed out (and me also a long time ago), an attribute based system makes it much harder to support multiple databases in many real-world cases.&quot;



    Attributes are just attributes. This doesn't mean that one can use some sort of mapping file, too.



    &quot;Finally, who doesn't support read after save, and you already know that I consider saving an entire context to be a questionable practice in most cases, but to each his own&quot;



    :-)

  • I think that David has a good point here. DLinq alone is a querying engine (sort of). ORM is done through DataContext which is a sepearate beast.

  • I have my own ORM also so when I heard about dlinq I was also wondering what place was left in the world for it. I agree with you that linq is great but dlinq is a poor substitute for a real ORM.



    I think you're overstating the importance of the fact that 99% of developers never use anything but what MS gives them. First off, MS is certainly giving them something much better than they've had before, so even for those people, dlinq is a step up.



    But more importantly, for those of us who *do* care about the features MS left out, the infrastructure invented to support dlinq pretty much guarantees that our own ORMs will be able to do cool stuff that's previously been unable to.



    For example, right now users of my ORM have to jump through hoops to do sorting - either by declaring several gets with different sort orders, or by doing stuff like:



    ArrayList people = Person.GetByAll();

    people.Sort(Person.LastNameOrder);

    foreach (Person person in people) {...}



    secondary sorts are even more awkward.



    Allowing stuff like:



    var people = from p in Person.GetByAll()

    orderby p.LastName, p.FirstName

    select p;



    is much nicer especially if it's possible to get the database to do that ordering, which I think it is (again, using the same technology developed for dlinq).

  • I was actually waiting for your comments on this, and you are pretty much spot on.



    One more point:

    One of my complaints about WinFS when introduced at PDC 2003 is that they introduced Yet Another Query Language. We've got Query Languages for WMI, MSI, SQL (and all subsets like T-SQL and PL-SQL), XPath, SNMP, and who knows what else. Now, added to the mix is Linq/DLinq/XLinq.



    As a 'front-line' developer, the only usefull thing that I can hope for out of all of this is a melding of query languages while working in a .NET world.



    I think you are correct when you state that because it is in the framework, this will become the defacto standard.



    --



    On a related note, what was more interesting to me than Linq was the idea of extension methods. To be introduced in C# 3.0, it provides a mechanism for adding functionality to existing (usually sealed) classes. Seriously cool stuff, though it should be used with care.

  • &quot;On a related note, what was more interesting to me than Linq was the idea of extension methods. To be introduced in C# 3.0, it provides a mechanism for adding functionality to existing (usually sealed) classes. Seriously cool stuff, though it should be used with care.&quot;

    The rest of the world calls that AOP and is generations ahead in that field compared to the .NET world, except perhaps spring.NET and some early bird weavers.



    Extension methods can IMHO be used to enable AOP elements, which is great, though this can already be done transparently, now, as spring.NET shows.



    For the people who think DLinq isn't an attempt to write an O/R mapper, it's my understanding that DLinq performs CRUD operations, not just retrieval. The document of DLinq for example mentions change tracking and why would anyone need changetracking if you don't save data? ;)

  • The DLinq document I linked to quite explicitly has persistence examples -- so that's not an open question.

  • Frans - Yes, I'm familiar with AOP - however, until support baked in, then it's unlikely that I will be able to use it. I don't drive such feature adoption in my organization. For me, Spring.NET (or O/R Mappers) are a tough sell. I've got a large team to convince. However, if a feature is part of the base language, then it is generally not an issue.

  • &quot;How will you build something on top of it without first defining these attribute based entities, and how will you add support for other databases if DLinq does not do so?&quot;



    I think you're not looking deep enough at the technology yet. You're letting the &quot;lameness&quot; of DLINQ, which I somewhat agree with, blind you from what really matters.



    LINQ is the base. DLINQ and XLINQ are built on top of LINQ. If you wanted to build your own ORM you don't build on top of DLINQ. You build something that is a sibling to DLINQ. You then build LINQ support for your custom ORM.



    So considering your existing architecture, you essentially keep exactly what you have now for configuring and representing entities and all you do is throw out whatever mechanism you came up with for querying and replace it with support for LINQ expressions.



    For example, for querying in my custom ORM implementation I have the concept of an EntityQuery, EntityQueryConditionGroup and EntityQueryCondition classes. EntityQuery is made up of multiple conditions as well as exposing sorting and paging semantics. These essentially get thrown out when I update my ORM implementation to work with link LINQ. Instead, I allow people to use LINQ and I translate the LINQ expressions into SQL statments just like DLINQ does to be as efficient as humanly possible for the backend data store I'm talking to. For example, you mentioned paging, I could be sure to issue a TOP statement to ensure I don't get back any more records than I really need. BTW, DLINQ *does* support this the same way, the expression is just a weird name which I can't remember off the top of my head.



    Ultimaely I believe that once you give it some more time you'll realize that how they implement DLINQ really doesn't matter. Focus on your ORM and be very comfortable in the fact that you'll be able to integrate with the rich querying syntax smoothly into languages using your own custom LINQ expressions.



    Cheers,

    Drew

  • Hi Drew:



    That I can agree with -- you are correct that I can build just on top of Linq. I guess my issue is that even though this can be really cool for my OR/M, its not enough since MS is also giving us DLinq. Why, since as you point out I can ignore DLinq? Because the vast majority of people and shops in the MS world expect you to use the MS implementation. If MS only gave us Linq then a decent minority would be willing to accept other mappers that took advantage of Linq. But once MS also gives us DLinq, then that will be what most people will use, and they will never look elsewhere or see that there is even a reason to do so. While I do really like my mapper, I know that I'll have far more clients that won't be willing to use it or any other mapper -- and since I'm a consultant far more than I am a vendor that is a big deal to me. I do think Linq is great, but I find it inexcusable that MS has worked over 5 years on OR/M and in their 3rd attempt now they have made a mess. What were they thinking?

  • Paul,



    Yeah, I hear ya. I guess that's less of an issue for me personally since I'm not a consultant.



    That said, this technology is way out there (probably 2008) and they were VERY open to feedback. If you really are worried about DLINQ's shortcomings, I highly recommend getting involved right now if you want to voice your opinions and maybe get some of the changes you'd like to see taken care of.



    I'm just extremely pleased with the base LINQ technology and that our own ORM implementations will be first class citizens with respect to the language syntax. :)

  • Your review sounds like sour grapes to me.

    If you want all customers just use:

    &quot;var q = Customers&quot;

    I don't see how you can get any more succinct than this. Inheritance will be the next feature added when they return to redmond, heck maybe in time for your MVP conference. WinFS integration with LINQ was shown at the conference.



    There are several severe limitations with Dlinq right now but lets kick the tires and get them to raise the bar.

  • Hm,



    I am heavily looking into the whole LINQ thing right now for the next generation of our EntityBroker... AND....



    It looks like while we WILL support LINQ (as &quot;ELinq&quot;), we will NOT throw out or own stuff. Because sadly LINQ is way too limited in it's expressions. Stuff like paging, load hints can not be represented - the query syntax is just too simple.



    As elegant as it is, sadly.

  • Just wondering if c# 3.0 is going to be released with visual studio 2005 and .net 2 in november 2005.



    All this new linq stuff looks cool but i'm wondering if its worth my time to looking into this if its not getting released for another year or something.



    thanks

  • Oh my no -- C# 2.0 will be released with VS 2005 and .NET v2.0 -- not C# 3.0. You're looking at 2007 or 2008 before C# 3.0 and .NET v3.0 comes out. PDCs are always about the next wave, not the current wave -- TechEd and other conferences are better suited for learning the current wave. So the question for you is are you preparing for 2.0 ?

  • I think adding some information here might help. DLinq was designed to be an extremely low entry point into ORM and to be used as an example of how to build a LINQ enabled API. Dlinq is a preview of technology that will likely change considerably before it ships, adding or changing features based on feedback. We decided to show this technology extremely early in its design so that by the time it ships it will be the right combination for a broad customer base. However, we anticpate that other ORM vendors offering superior features will also choose to LINQ enable their products to take advantage of language integrated query. This was indeed a goal of LINQ's design, keeping the language features entirely separate from the API's.



    At this point, the design of DLinq has been biased heavily toward rich query support with an API targetted toward simplicity. This has lead to trade-offs in what is available today, such as attribute based mapping declarations and a class of mapping that is not much more than one-to-one with the database. While these may not scale to the kind of applications handled by ORM's such as Paul's, they are indeed simpler to define, easier to grasp and quicker to make use of.

    Still, our intention is not to leave DLinq in this state, but to advance it to include some of the more popular ORM features such as inheritance, many-to-many mapping, events, support for additional databases and so on, depending on the kind of feedback we get.



    Remember, this is not a finished product nor is it even a beta. It is not a revision of ObjectSpaces, yet it is based on many lessons we learned from building both ObjectSpaces and C-Omega. We've previewed it early so you can tell us what is most important to you.

  • Christoffer:

    While you can run the Linq preview with VS 2005, it works only by redirecting to a preview C# 3.0 compiler. It is not part of VS 2005, .NET v2.0, or C# 2.0 -- nor will it become part of that, other than a preview.



    Matt:

    Thank's for the explanation. Its very good, but its still extremely frustrating to keep hearing that this is just an early preview when we know MS has 5+ years experience wrapped up in O/RM. I still haven't heard anyone explain why ObjectSpaces wasn't turned into DLinq.

  • LINQ does not require version 3.0 of the .Net _framework_. It will work with v 2.0 of the framework.

    What it does require is new compilers. The c# 3.0 compilers and VB.Net 9.0 compilers will be part of ORCAS which *may* very well be released before a version 3.0 of the .Net framework...and hopefully before 2008 ;-)

  • I have written a small project about LINQ and DLinq. This might an interesting read for some of you guys.

  • The only thing scarying me is the lack of updates to WilsonORMapper.... :)

  • Yea, I've got some half done and never had the time and energy to finish them. Lots of changes in my life to blame, all of which I'm making efforts to fix, or already have fixed in many cases. Luckily DLinq, now called LINQ to SQL, is looking better and better with each drop. :)

  • hehe,

    glad to hear you say that - I was just installing it yesterday, did some Linq for the first time over a Dlinq model I created, and I was pretty impressed.

    Granted Paul, I agree, it's probably not perfect, but it's making progress and it's definitely easy to get started with.

    :)

    I didn't mean to knock you by the way, you've done a great job on your tool and I felt it was definitely worth the money I paid to help support it!

  • Hi Paul,

    I'd be interested to learn your up-to-date opinion on LINQ to SQL. I also thought very little about DLinq when it first arrived on the radar back in 2005. However, i have to say that having experimented with the latest CPT I'm pretty impressed in general.

    Cheers,

    Chris.

  • Hi Chris:

    I noted in a previous post, and in some comments on this thread, that LINQ to SQL is definitely looking much better to me. I still haven't had time to play with the March 2007 CTP though, so I'm not in a position to comment more yet.

    Thanks, Paul Wilson

Comments have been disabled for this content.