1

我得到了一个列表,其中包含每个订单的所有状态项。我遇到的问题是我需要删除所有 status -> logdate 组合不是最高的项目。

例如

        var inputs = new List<StatusItem>();
        //note that the 3th id is simply a modifier that adds that amount of secs
        //to the current datetime, to make testing easier
        inputs.Add(new StatusItem(123, 30, 1));
        inputs.Add(new StatusItem(123, 40, 2));
        inputs.Add(new StatusItem(123, 50, 3));
        inputs.Add(new StatusItem(123, 40, 4));
        inputs.Add(new StatusItem(123, 50, 5));

        inputs.Add(new StatusItem(100, 20, 6));
        inputs.Add(new StatusItem(100, 30, 7));
        inputs.Add(new StatusItem(100, 20, 8));
        inputs.Add(new StatusItem(100, 30, 9));
        inputs.Add(new StatusItem(100, 40, 10));
        inputs.Add(new StatusItem(100, 50, 11));
        inputs.Add(new StatusItem(100, 40, 12));

        var l = from i in inputs
                group i by i.internalId
                    into cg
                    select
                             from s in cg
                             group s by s.statusId
                                 into sg
                                 select sg.OrderByDescending(n => n.date).First()
                    ;

编辑:为方便起见,我也添加了类定义。

  public class StatusItem
  {
            public int internalId;
            public int statusId;
            public DateTime date;

            public StatusItem(int internalId, int statusId, int secMod)
            {
                this.internalId = internalId;
                this.statusId = statusId;
                date = DateTime.Now.AddSeconds(secMod);
            }
  } 

这将创建一个返回我以下内容的列表:

订单 123 状态 30 日期 2010 年 4 月 9 日下午 6:44:21
订单 123 状态 40 日期 2010 年 4 月 9 日下午 6:44:24
订单 123 状态 50 日期 2010 年 4 月 9 日下午 6:44:25

订单 100 状态 20 日期 2010 年 4 月 9 日下午 6:44:28
订单 100 状态 30 日期 2010 年 4 月 9 日下午 6:44:29
订单 100 状态 40 日期 2010 年 4 月 9 日下午 6:44:32
订单 100状态 50 日期 2010 年 4 月 9 日下午 6:44:31

这几乎是正确的。然而,状态为 50 的最后一行也需要被过滤掉,因为它被历史列表中的状态 40 否决了。您可以通过它的日期低于状态为 40 的“最后一个”状态项这一事实来判断。

我希望有人能给我一些指示,因为我卡住了。

编辑:最终完整的解决方案:

  var k = from sg in
                    from i in inputs
                     group i by i.internalId
                         into cg
                         select
                                  from s in cg
                                  group s by s.statusId
                                      into sg
                                      select sg.OrderByDescending(n => n.date).First()
                from s in sg
                where s.date >= sg.Where(n => n.statusId <= s.statusId).Max(n => n.date)
                group s by s.internalId
                    into si
                    from x in si
                    select x;
4

2 回答 2

1

看起来您目前没有任何执行日期所需的过滤,因此您需要对此做一些事情。

顺便说一下,这样的事情会执行额外的过滤:

        var k = from sg in l
                from s in sg
                where s.date >= sg.Where(n => n.statusId <= s.statusId).Max(n => n.date)
                group s by s.internalId;

尚未对其进行测试,因此分组可能不是您想要的,并且比较可能会颠倒,但是应该过滤类似的东西。 >=<=不是>or<应该意味着状态将始终与自身进行比较,而不必处理聚合问题中的空集。

于 2010-04-09T19:55:45.303 回答
0

它与您的形式不完全相同,但确实给出了正确的结果。我用 i、j 和 k 属性创建了一个状态项类。不确定您为他们使用的名称。

var keys = inputs.Select(
    input =>
        new { i = input.i, j = input.j })
.Distinct();

var maxes = keys.Select(
    ints =>
        inputs.First(
            input =>
                input.i == ints.i
             && input.j == ints.j
             && input.k == inputs.Where(
                               i =>
                                   i.i == ints.i
                                && i.j == ints.j
                            ).Select(i => i.k).Max()));
于 2010-04-09T18:20:04.070 回答