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

リフレクターは私に次のことを教えてくれます:

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言うように、グループが空にならないのでin place は必要ありませんが、はありません。)FirstOrDefaultFirst

于 2012-11-13T08:48:24.547 に答える
3

内包クエリ構文には演算子はありませんFirstOrDefault(アイテムがグループ化されている場合、少なくとも 1 つのアイテムがグループ内に存在するため、必要です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 を返します

ところで、LINQ Pad によると、このクエリは、ネストされたクエリとまったく同じ SQLを生成しますfrom x in g orderby x.Date descending select x

UPDATEまた、私の悪い - FirstLINQ to Objects、またはLINQ to SQLで動作しますが、LINQ to Entitiesでは使用する必要がありますFirstOrDefault。そして2番目の注意-これらのクエリ(私のクエリとネストされたクエリを使用)は、LINQ to SQLに対して同じSQLを生成しますが、EFでは私の順序付けは適用されません。

于 2012-11-13T08:43:09.117 に答える