5

您将如何使用 LINQ 查询语法编写这个完全相同的查询?

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

我虽然这应该工作,但它没有:

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

如果你想玩它,这里有一个测试程序:

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

2 回答 2

3

理解查询语法中没有FirstOrDefault运算符(如果项目被分组,那么至少一个项目将出现在组中,所以你需要First),但其他的东西是这样翻译的:

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

诀窍是,如果您按有序顺序进行分组,则会对组中的项目进行排序。瞧:

q1.SequenceEqual(q2)返回真

顺便说一句,根据 LINQ Pad,此查询生成完全相同的 SQL,与嵌套查询from x in g orderby x.Date descending select x

更新也是我的坏 -First将与 LINQ to Objects 或 LINQ to SQL 一起使用,但与 LINQ to Entities 你应该使用FirstOrDefault. 第二个注意事项 - 这些查询(我的查询和嵌套查询)将为 LINQ to SQL 生成相同的 SQL,但使用 EF 我的排序不适用。

于 2012-11-13T08:43:09.117 回答
3

反射器给了我以下信息:

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();

看起来是对的。

(如前所述Lazy,没有必要FirstOrDefault代替,因为First组不会是空的,但它不会受到伤害。)

于 2012-11-13T08:48:24.547 回答