将EF LINQ方法语法转换为查询语法

时间:2012-11-13 08:38:44

标签: c# linq linq-query-syntax

您如何使用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));
}

2 个答案:

答案 0 :(得分: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)返回true

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

UPDATE 另外我的错误 - First将与LINQ to Objects或LINQ to SQL一起使用,但对于LINQ to Entities,您应该使用FirstOrDefault。第二个注意事项 - 这些查询(我和嵌套查询)将为LINQ to SQL生成相同的SQL,但是使用EF我的排序不会被应用。

答案 1 :(得分:3)

Reflector给了我以下内容:

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没有需要,因为这些群组不会为空,但它不会。)