Linq子查询 - 带

时间:2014-12-13 18:01:33

标签: linq subquery grouping

处理我有一组与赛马有关的数据的问题。像这里:

        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查询 - 提供一个谓词来选择数据中的初始项,然后返回每个符合条件的马的后续x记录

一个例子;给出这些数据,以及具有FinishPositionVal = 3的初始项目的谓词,并为所有匹配的跑步者进行2次随后的出游......应该返回ID为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);

此部分返回初始谓词匹配的所有后续外出。我可以将这个返回集合分组,并从每个跑步者中取出前x ..但这不正确。因为......谓词独立地从数据中的两个独立点开始:从ID 3,4,位置= 3,所以应该从每个点开始2次后续出现...即ID 4,由于ID3匹配谓词,应该拾取5,并且ID5,6由于ID4匹配谓词而被拾取...然后4,5,5,6 distinct应该留下4,5,6 ....

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

由于

1 个答案:

答案 0 :(得分:0)

对于Matt Ko,我提出的加入查询是:

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

这适用于获取后续运行,现在我想限制结果集在初始运行谓词选择运行后仅执行后续运行中的2个。我知道,为了获得排位赛之后的下一轮比赛,我可以使用:

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