Convert EF LINQ Method Syntax to Query Syntax

How could you write this same query using LINQ query syntax?

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

Although this should work, but it is not:

 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 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)); } 
+4
source share
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 right.

(As Lazy says that instead of First there is no need for FirstOrDefault , since the groups will not be empty, but this will not hurt.)

+2
source

There is no FirstOrDefault statement in the understanding query syntax (if the elements are grouped, then at least one element will be represented in the group, so you need First ), but other things translate like this:

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

The trick is that the elements in the group will be ordered if you are grouping in an ordered sequence. And voila:

q1.SequenceEqual(q2) returns true

By the way, according to LINQ Pad, this query generates exactly the same SQL as a 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 the second note - these queries (mine and with a subquery) will generate the same SQL for LINQ to SQL, but with EF my order is not applied.

+2
source

Source: https://habr.com/ru/post/1445714/


All Articles