Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert EF LINQ method syntax to query syntax

How would you write this exact same query using the LINQ query syntax?

var q2 = list.GroupBy(x => x.GroupId)
             .Select(g => g
                 .OrderByDescending(x => x.Date)
                 .FirstOrDefault());

I though this should work but it didn't:

var q1 = from x in list
         group x by x.GroupId into g
         from y in g
         orderby y.Date descending
         select g.FirstOrDefault();

Here's a test program if you want to play around with it:

public class MyClass
{
    public int Id { get; set; }
    public string GroupId { get; set; }
    public DateTime Date { get; set; }

    public override bool Equals(object obj)
    {
        var item = obj as MyClass;
        return item == null ? false : item.Id == this.Id;
    }
}

static void Main(string[] args)
{
    var list = new List<MyClass> 
    {
        new MyClass { GroupId = "100", Date=DateTime.Parse("01/01/2000"), Id = 1},
        new MyClass { GroupId = "100", Date=DateTime.Parse("02/01/2000"), Id = 2},
        new MyClass { GroupId = "200", Date=DateTime.Parse("01/01/2000"), Id = 3},
        new MyClass { GroupId = "200", Date=DateTime.Parse("02/01/2000"), Id = 4},
        new MyClass { GroupId = "300", Date=DateTime.Parse("01/01/2000"), Id = 5},
        new MyClass { GroupId = "300", Date=DateTime.Parse("02/01/2000"), Id = 6},
    };

    var q1 = from x in list
                group x by x.GroupId into g
                from y in g
                orderby y.Date descending
                select g.FirstOrDefault();

    var q2 = list.GroupBy(x => x.GroupId)
                    .Select(g => g
                        .OrderByDescending(x => x.Date)
                        .FirstOrDefault());

    Debug.Assert(q1.SequenceEqual(q2));
}
like image 249
Eren Ersönmez Avatar asked Nov 13 '12 08:11

Eren Ersönmez


People also ask

How LINQ queries converted into SQL queries?

LINQ to SQL translates the queries you write into equivalent SQL queries and sends them to the server for processing. More specifically, your application uses the LINQ to SQL API to request query execution. The LINQ to SQL provider then transforms the query into SQL text and delegates execution to the ADO provider.

What is query syntax and method syntax in LINQ?

Query syntax and method syntax are semantically identical, but many people find query syntax simpler and easier to read. Some queries must be expressed as method calls. For example, you must use a method call to express a query that retrieves the number of elements that match a specified condition.

Does LINQ support method syntax?

Linq namespace generally uses method syntax. Therefore, even when getting started writing LINQ queries, it is useful to be familiar with how to use method syntax in queries and in query expressions themselves.

What is method syntax in C# LINQ?

In LINQ, Method Syntax is used to call the extension methods of the Enumerable or Queryable static classes. It is also known as Method Extension Syntax or Fluent. However, the compiler always converts the query syntax in method syntax at compile time.


2 Answers

Reflector gives me the following:

var q2 = from x in list
         group x by x.GroupId into g
         select (
             from x in g
             orderby x.Date descending
             select x).FirstOrDefault();

which looks about right.

(As Lazy says, there's no need for FirstOrDefault in place of First as the groups won't be empty, but it doesn't hurt.)

like image 191
Rawling Avatar answered Oct 04 '22 13:10

Rawling


There is no FirstOrDefault operator in comprehension query syntax (if items are grouped, then at least one item will present in group, so you need First), but other stuff is translated like this:

var q1 = from c in list
         orderby c.Date descending
         group c by c.GroupId into g
         select g.First();

Trick is that items in group will be ordered, if you do grouping on ordered sequence. And voilà:

q1.SequenceEqual(q2) returns true

BTW according to LINQ Pad this query generates exactly same SQL, as query with nested from x in g orderby x.Date descending select x

UPDATE Also my bad - First will work with LINQ to Objects, or LINQ to SQL, but with LINQ to Entities you should use FirstOrDefault. And second note - these queries (my and with nested query) will generate same SQL for LINQ to SQL, but with EF my ordering is not applied.

like image 43
Sergey Berezovskiy Avatar answered Oct 04 '22 14:10

Sergey Berezovskiy