60

I am beginning to use LINQ in general (so far toXML and toSQL). I've seen that sometimes there are two or more ways to achieve the same results. Take this simple example, as far as I understand both return exactly the same thing:

SomeDataContext dc = new SomeDataContext();

var queue = from q in dc.SomeTable
        where q.SomeDate <= DateTime.Now && q.Locked != true
        orderby (q.Priority, q.TimeCreated)
        select q;

var queue2 = dc.SomeTable
        .Where( q => q.SomeDate <= DateTime.Now && q.Locked != true )
        .OrderBy(q => q.Priority)
        .ThenBy(q => q.TimeCreated);

The idea is that there are two ways to express the same thing; I understand that the first method has some limitations and that the "dot notation" is more complete, but besides that, are there any other advantages?

Rowan Richards
  • 401
  • 8
  • 20
Martin Marconcini
  • 26,875
  • 19
  • 106
  • 144

5 Answers5

60

The "dot" notation is usually called Lambda syntax. The first notation goes by a number of names but I usually call it the query syntax.

I work on a team of 10 developers and we argue at length about which we should use as a standard. In general, the more seasoned (with LINQ) developers migrate towards the Lambda syntax but there are significant exceptions.

Lambda is more concise but performing multiple table joins is a nightmare. Joins are just much cleaner with the query syntax. The flip side is that there are a number of LINQ operations that only exist within the Lambda syntax: Single(), First(), Count() etc.

So, use what you feel most comfortable with and realize that as you gain experience, your preference will likely change. There is great value in being able to read both and there will certainly be situations where you have to use a little bit of both. Other situations will lend themselve to one style over the other. In the end, it all gets translated into the same executable code.

andleer
  • 22,388
  • 8
  • 62
  • 82
  • 2
    5 years later and the method-chained lambda syntax is now commonly referred to as a [Fluent Interface](http://en.wikipedia.org/wiki/Fluent_interface). – Nick Sep 09 '14 at 17:00
  • 3
    4 years later and Microsoft seems to distinguish between Query and Method syntax: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/query-syntax-and-method-syntax-in-linq – Chris Jul 20 '18 at 11:12
  • 1
    9 years later and I haven't done .NET programming in 7 years. But this was a *great* answer back in 2010 and still is today. Thank you andleer :) – Martin Marconcini Jul 11 '19 at 10:52
  • @MartinMarconcini Happy to lend a hand. -Andrew Robinson – andleer Nov 07 '19 at 04:00
  • @andleer I guess I should reply in 7-9 years, but just in case (because I'm getting old), _future_ *thanks again* – Martin Marconcini Nov 07 '19 at 15:46
29

I use whichever syntax is more readable for my query, on a case-by-case basis.

Where possible, I try to avoid mixing and matching the two, although sometimes it's okay (if it's a single call to First() at the end of a query, for example). Deferred execution means it's just as efficient to use a query expression and assign the result to a variable, and then use dot notation using that variable:

var query = from x in y
            orderby z
            group x by x.Name into groups
            // etc
            select foo;

var page = query.Skip(50).Take(10);

As others have said, query expressions are just translated into "normal" C# 3 without query expressions, so there's no penalty for doing this.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 3
    +1 again for splitting the two when you want to use them together rather than wrapping the first in parentheses and tacking the rest onto the end. – Shibumi Jun 30 '11 at 20:33
8

Well, the 'dot' notation can be much shorter. Take:

var result = from p in dc.Products
             where p.Id > 5
             select p;

or:

var result = dc.Products.Where(p => p.Id > 5);

I prefer the latter since it is much shorter, and more readable.

Razzie
  • 30,834
  • 11
  • 63
  • 78
  • When using LINQ to SQL I prefer the former because it's closer to T-SQL (which is handy when writing DB queries) and the latter for other LINQ queries (like LINQ to XML). – RobS Mar 10 '09 at 13:33
  • Yes, you have a point there. With linq2sql I often use the first version, for the same reason you mention. Although I must also admit that for very simple queries like the one above, I often use the second, short version, just because I'm lazy :-) – Razzie Mar 10 '09 at 13:43
  • It's not ALWAYS shorter, and sometimes it's harder to read, but you have a point that it can be a bit shorter. – Meta-Knight Aug 19 '09 at 13:16
  • Well of course, you're right. But if you notice in my first sentence, I said that it *can* be much shorter :-) But yeah, from my own experience and like andrew said, sometimes it can become long and barely readable, in cases of joins for example. – Razzie Aug 20 '09 at 07:35
3

I find Lambda notation neater and more concise. I just find it annoying that if you have a Lambda expression anywhere inside a method call, you can't modify code on the fly in debug mode...

Shaul Behr
  • 36,951
  • 69
  • 249
  • 387
2

They compile to the same code, or rather first one is first translated to the second and then compiled.

You are right that the difference is that first version is cleaner but more limited. In the second you can for example use already existing delegates, e.g.:

Func<int, bool> isEven = i => i%2 == 0;
Enumerable.Range(10).Where(isEven).ToList().ForEach(Console.WriteLine);
user76035
  • 1,526
  • 1
  • 10
  • 12
  • Not entirely true. You can use still use an exisiting delegate, for example: var result = from s in list where isEven.Invoke(s.Length) select s; – Razzie Mar 10 '09 at 13:14
  • 1
    you don't need to use Invoke, this works just fine: var result = from i in ints where isEven(i) select i; – theburningmonk Feb 13 '10 at 13:11