2014-12-13 4 views
-1

Работа над проблемой, где у меня есть набор данных, связанных с скачками. Как здесь:Linq subquery - with take

 outingsData = new List<RPOutingFull>(); 
     outingsData.Add(new RPOutingFull() { ID = 1, HorseID = hid1, FinishPositionVal = winPos, theDate = outingsStartDate.AddDays(-5) }); 
     outingsData.Add(new RPOutingFull() { ID = 2, HorseID = hid1, FinishPositionVal = winPos, theDate = outingsStartDate.AddDays(-4) }); 
     outingsData.Add(new RPOutingFull() { ID = 99, HorseID = 2, FinishPositionVal = winPos, theDate = outingsStartDate.AddDays(-4) }); 
     outingsData.Add(new RPOutingFull() { ID = 3, HorseID = hid1, FinishPositionVal = 3, theDate = outingsStartDate.AddDays(-1) }); 
     outingsData.Add(new RPOutingFull() { ID = 4, HorseID = hid1, FinishPositionVal = 3, theDate = outingsStartDate.AddDays(+1) }); 
     outingsData.Add(new RPOutingFull() { ID = 5, HorseID = hid1, FinishPositionVal = 6, theDate = outingsStartDate.AddDays(+4) }); 
     outingsData.Add(new RPOutingFull() { ID = 6, HorseID = hid1, FinishPositionVal = winPos, theDate = outingsStartDate.AddDays(+5) }); 
     outingsData.Add(new RPOutingFull() { ID = 7, HorseID = hid1, FinishPositionVal = winPos, theDate = outingsStartDate.AddDays(+22) }); 
     outingsData.Add(new RPOutingFull() { ID = 8, HorseID = 3, FinishPositionVal = winPos, theDate = outingsStartDate.AddDays(+22) }); 
     outingsData.Add(new RPOutingFull() { ID = 9, HorseID = 5, FinishPositionVal = 2, theDate = outingsStartDate.AddDays(+27) }); 
     outingsData.Add(new RPOutingFull() { ID = 10, HorseID = 5, FinishPositionVal = 4, theDate = outingsStartDate.AddDays(+55) }); 
     outingsData.Add(new RPOutingFull() { ID = 11, HorseID = 5, FinishPositionVal = 4, theDate = outingsStartDate.AddDays(+56) }); 
     outingsData.Add(new RPOutingFull() { ID = 12, HorseID = 5, FinishPositionVal = 5, theDate = outingsStartDate.AddDays(+95) }); 
     outingsData.Add(new RPOutingFull() { ID = 13, HorseID = 5, FinishPositionVal = 6, theDate = outingsStartDate.AddDays(+96) }); 

Я хочу написать Linq запрос - что обеспечивает предикат, чтобы выбрать начальный элемент в данных, а затем вернуть последующие х записи для каждой квалификационной лошади

Пример; с учетом этих данных, а предикат исходного пункта, имеющего FinishPositionVal = 3, и принимая 2 из последующих экскурсий для всех соответствующих полозьев ... должен возвращать элементы с идентификаторами 4,5,6

 // take next 2 outings 
     int takeCount = 2; 
     Predicate<RPOutingFull> predicate = full => full.FinishPositionVal == 3; 

     var resAllSubsequentOutings = (from s1 in outingsData 
        from s2 in outingsData 
        where 
        s2.theDate > s1.theDate && s1.HorseID == s2.HorseID && 
        predicate(s1) 
        orderby s1.theDate 
        select s2); 

Эта часть возвращает все последующие выходы, где совпадает исходный предикат. Я мог бы сгруппировать этот набор возвратов и взять верхний х от каждого бегуна. Но это неверно. Потому что ..... предикат самостоятельно начинал с двух отдельных точек в данных: от ID 3, 4 (где позиция = 3), поэтому взятие должно быть для двух последующих выходов из каждой точки ... т.е. ID 4, 5 следует подбирать из-за предиката, соответствующего ID3, и ID5,6, собранного из-за ID4-совместимого предиката ... тогда 4,5,5,6 отдельных должны уйти с 4,5,6 ....

 CollectionAssert.AreEquivalent(new List<long>() { 4, 5, 6 }, resMissingQuery.Select(o => o.ID)); 

Благодаря

+0

Найдено решение этой проблемы после адаптации запроса от: http://stackoverflow.com/questions/880665/stuck-on -a-подзапрос-что-это-группировка-в-LINQ –

+0

Решение: вар Q = (от s1 в outingsData из г в ( из s2 в outingsData где s2.theDate> s1.theDate && s1.HorseID = = s2.HorseID && предикат (s1) orderby s1.theDate select s2) .Take (takeCount) выбрать g) .Distinct ().К списку(); –

+0

Я пытаюсь переписать это как запрос соединения, чтобы повысить производительность ... Это не так просто. Любая помощь оценивается. –

ответ

0

Для Мэтта Ко, объединение запросов Я пришел вверх с:

 Predicate<RPOutingWithNoComment> predicate = r => r.FinishPositionVal == 3; 
     var res = (from s1 in _testData 
        join s2 in _testData on s1.HorseID equals s2.HorseID 
        where s2.theDate > s1.theDate && 
         s1.HorseID == s2.HorseID && predicate(s1) 
        orderby s2.theDate 
        select s2).Distinct(); 

Это работает на получение последующих запусков, теперь я хочу ограничить набор результатов только двумя последующими прогонами ПОСЛЕ того, как предикат начального запуска выбирает прогон. Я знаю, чтобы получить только следующий запуск после отборочного запуска, я могу использовать:

 var q = from r in res 
      group r by r.HorseID 
      into g 
      select g.OrderBy(o => o.theDate).First();