2016-06-08 33 views
1

Ich versuchteMultiple ROW_NUMBER in LINQ

select * 
from (
    select *, rng = row_number() over (partition by grp order by id) 
    from (
    select *, grp = row_number() over (order by id) - row_number() over (partition by Name, Status, DateFinished order by id) 
    from tooling) g 
) gn 
where rng = 1 
order by id 

aus einer früheren Frage (Grouping with partition and over in TSql)

Mit Hilfe zu übersetzen mit Row_number over (Partition by xxx) in Linq? bekam ich die Lösung ONE der row_number s zu übersetzen, aber scheint I'am Pech gehabt, die ganze Frage erfolgreich zu übersetzen?
Mein Versuch:

Tooling.OrderBy(x => x.Id) 
    .GroupBy(x => new {x.Name,x.Status,x.DateFinished}) 
    .Select(group => new { Group = group, Count = group.Count() }) 
    .SelectMany(groupWithCount => 
     groupWithCount.Group.Select(b => b) 
     .Zip(
      Enumerable.Range(1, groupWithCount.Count), 
      (j, i) => new { j.Name,j.Status, j.DateFinished, RowNumber = i } 
     ) 
    ) 

Antwort

0

versuchen, eine andere Art und Weise zu verwenden, um das Ergebnis mit LINQ zu erhalten. Holen Sie sich den bisherigen Rekord mit ID < dem Strom Id und überprüfen, ob alle Felder gleich:

var Res = Tooling.Where(x=>{ var r = Tooling.Where(y=>y.Id<x.Id).OrderByDescending(y=>y.Id).FirstOrDefault(); 
            if (r==null) return true; 
            return !((r.Name==x.Name) && (r.Status==x.Status) && (r.DateFinished==x.DateFinished)); 
            }) 
         .OrderBy(x => x.Id) 
         .Select(x=>x); 

UPD: Hier ist eine Testroutine:

public class TollingRecord 
{ 

    public int Id; 
    public String Name; 
    public int Status; 
    public DateTime? DateFinished; 

} 

...

private static void TestT1() 
     { 
      TollingRecord[] Tooling = new TollingRecord[]{ new TollingRecord() {Id=1, Name="Large", Status=0, DateFinished=null }, 
          new TollingRecord() {Id=2, Name="Large", Status=1, DateFinished=null}, 
          new TollingRecord() {Id=3, Name="Small", Status=0, DateFinished=null}, 
          new TollingRecord() {Id=4, Name="Large", Status=2, DateFinished=null}, 
          new TollingRecord() {Id=5, Name="Large", Status=2, DateFinished=null}, 
          new TollingRecord() {Id=6, Name="Large", Status=1, DateFinished=null}, 
          new TollingRecord() {Id=7, Name="Large", Status=1, DateFinished=null}, 
          new TollingRecord() {Id=8, Name="Small", Status=1, DateFinished=DateTime.Now}, 
          }; 



      var Res = Tooling.Where(x=>{ var r = Tooling.Where(y=>y.Id<x.Id).OrderByDescending(y=>y.Id).FirstOrDefault(); 
             if (r==null) return true; 
             return !((r.Name==x.Name) && (r.Status==x.Status) && (r.DateFinished==x.DateFinished)); 
             }) 
          .OrderBy(x => x.Id) 
          .Select(x=>x); 


      foreach (var a in Res) 
      { 
       Console.WriteLine("{0}/{1}/{2}", a.Id,a.Name,a.Status); 
      } 

     } 

Ausgänge:

1/Large/0 
2/Large/1 
3/Small/0 
4/Large/2 
6/Large/1 
8/Small/1 
+0

Leider scheint dieser Vorschlag keine Antwort zu geben –

+0

@JerkerPihl Ich habe ein Testverfahren hinzugefügt, um zu zeigen, dass es funktionieren muss. – valex

+0

Ich werde auf Ihre Antwort in ein paar Tagen schauen :) –