2016-06-08 10 views
1

Я попытался перевестиMultiple row_number в 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 

от ранее вопрос (Grouping with partition and over in TSql)

С помощью с Row_number over (Partition by xxx) in Linq? я получил решение перевести ОДНО из row_number s, но кажется i'am не повезло, чтобы успешно перевести весь вопрос?
Моя попытка:

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 } 
     ) 
    ) 

ответ

0

Попробуйте использовать другой способ, чтобы получить результат с помощью LINQ. Получить предыдущую запись с ID < тока Id и проверить, если все поля то же самое:

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: Вот тест рутина:

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

     } 

Выходы:

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

К сожалению, это предложение, похоже, не дает никакого ответа –

+0

@JerkerPihl Я добавил процедуру тестирования, чтобы показать, что она должна работать. – valex

+0

Я посмотрю на ваш ответ через несколько дней :) –