Long and complex queries in the syntax of methods can become unreadable - especially with the frequent use of anonymous classes. The same query syntax hides these anonymous classes from you:
var q1 = trees.SelectMany(t => t.Leaves.Select(l => new { tree = t, leaf = l })) .OrderBy(x => x.leaf.color) .Select(x => x.tree.name);
Try rewriting the query above without an anonymous class. But in longer queries, either nested anonymous classes may appear - or permanent copies from one anonymous class to another.
When using the query syntax, many anonymous classes successfully hide:
var q1 = from tree in trees from leaf in tree.Leaves order by leaf.Color select tree.Name;
Also in long queries, when using methods, you can quickly get bored with writing the same prefix for each closure - in the query syntax the same range variable is defined only once.
For this reason, in complex queries, query syntax is usually preferable.
On the other hand, some things are simply impossible to do in the query syntax.
For example, method overloads that take IEqualityComparer
can only be called as methods.
Also, the syntax of the methods allows you to "accumulate" a complex query in a variable depending on external conditions - which is useful when processing filtering blocks:
if (filters.Foo.HasValue) q = q.Where(x => x.Foo == filters.Foo); if (filters.Bar != null) q = q.Where(x => x.Bar.Name == filters.Bar);