2015-10-13 3 views
8

Ich möchte Daten von Row_number über Partition mit EF laden.Zeilennummer über (Partition von yyy) in Entity Framework

SELECT * 
    FROM (
     SELECT sf.SerialFlowsId 
        ,sf.GoodsSerialId 
        ,d.FormTypeId 
        , d.GoodsId 
        ,ROW_NUMBER() OVER (PARTITION BY d.GoodsId, sf.GoodsSerialId ORDER BY sf.Date DESC)row 
     FROM sam.SerialFlows sf 
     INNER JOIN sam.Detail d ON d.DetailId = sf.DetailId 
     )z 
WHERE z.row =1 
     AND z.FormTypeId=7 
     AND z.GoodsId=51532 

diese Abfrage ist meine Erwartung.

Ich versuche, diesen Ausdruck zu benutzen, aber leider Zip-Extension-Methode in ef nicht erkennen

var goodsSerials = context.SerialFlows.OrderByDescending(x => x.Date).GroupBy(x => new { x.Detail.GoodsID, x.Date }) 
        .Select(g => new {g}) 
        .SelectMany(z => z.g.Select(c => c)).Zip(m, (j, i) => new { GoodSerial=j,j.Detail.FormTypeID,j.Detail.GoodsID,rn=i }) 
        .Where(x => x.rn== 1 && x.GoodsID== goodsId && x.FormTypeID==7).Select(x => x.GoodSerial).ToList(); 

Ich habe mehr als 20 Millionen Datensätze in SerialFlows Tabelle.

** Herausgegeben

var goodsSerials = context.SerialFlows 
              .Where(e => e.Detail.GoodsID == goodsId) 
              .GroupBy(x => x.GoodsSerialID) 
              .Select(g => g.OrderByDescending(e=>e.Date).Take(1)) 
              .SelectMany(e => e.Where(x=>x.Detail.FormTypeID==7).Select(z=>z.GoodsSerial)).ToList(); 

*** durch diese Abfrage Gelöst

 var goodsSerials = context.SerialFlows 
              .Include(x => x.Detail) 
              .Where(e => e.Detail.GoodsID == goodsId) 
              .GroupBy(x => x.GoodsSerialID) 
              .Select(g => g.OrderByDescending(e => e.Date).Take(1).Where(x=>x.Detail.FormTypeID==7)) 
              .SelectMany(e => e.Select(z => z.GoodsSerial)).ToList(); 
+2

Warum der Downvote? Scheint mir eine vollkommen gute Frage zu sein. – pseudocoder

Antwort

8

Von SQL-Abfrage, ich glaube, Sie brauchen, um erste Gruppe sie alle von dem, was in PARTITION BY Klausel, jede Bestellung Gruppe nach Datum. Projizieren Sie dann jede Gruppe, um jeden Eintrag mit seinem Index einzuschließen. Dann , um alle Gruppen zu reduzieren, dann Filter anwenden und schließlich das gewünschte Ergebnis projizieren. Sie können sehen, dass wir die sogenannte Zip überhaupt nicht benötigen.

bearbeiten: weil Sie auf die Zeilennummer filtern, sondern sieht aus wie die Select Verfahren zur Annahme eines Expression<Func<T,int,TResult>> nicht unterstützt wird (wie auch die Zip Methode in Linq To Entity). Ich glaube nicht, dass es das Problem ist, den Ausdrucksbaum zu erstellen, was bedeutet, dass er sogar manuell erstellt wird. Er wird dennoch nicht unterstützt. Ich denke, dass Sie eine Problemumgehung verwenden können, in der Sie die Zeile, die Sie möchten, stattdessen mit Skip und Take stattdessen filtern können.

Der folgende Code wird filtern, dass nur die erste Zeile in jeder Gruppe (äquivalent zu der Bedingung rn == 1):

var goodsSerials = context.SerialFlows 
          .Where(e => e.Detail.GoodsID == goodsId && 
             e.Detail.FormTypeID == 7) 
          .GroupBy(x => new { x.Detail.GoodsID, x.GoodsSerialId }) 
          .Select(g => g.OrderByDescending(e => e.Date) 
             .Take(1)) 
          .SelectMany(e => e).ToList(); 

Die Where Filter für nur 1-Wert von GoodsID so die GroupBy braucht nicht die GoodsID einzubeziehen in den Schlüssel, so wäre es einfacher so aussehen:

var goodsSerials = context.SerialFlows 
          .Where(e => e.Detail.GoodsID == goodsId && 
             e.Detail.FormTypeID == 7) 
          .GroupBy(x => x.GoodsSerialId) 
          .Select(g => g.OrderByDescending(e => e.Date).Take(1)) 
          .SelectMany(e => e).ToList(); 

ich Ihnen die Idee der Verwendung von Skip undverstehen hoffenin verschiedenen Fällen anwenden.

+0

unwillkürlich ich habe Fehler.Zusätzliche Informationen: LINQ to Entities erkennt die Methode 'System.Collections.Generic.IEnumerable –

+0

@ MahdiFarhani sehe meine Bearbeitung, sieht aus wie wir kaum die Zeilennummer extrahieren können, aber zum Zwecke der Filterung Wir haben einen schönen Work-Around. –

+0

es läuft, aber die Leistung ist nicht akzeptabel. Es dauert über 4 Minuten und ich habe es abgebrochen. –