【问题标题】:Combine multiple Linq Where statements组合多个 Linq Where 语句
【发布时间】:2015-12-08 09:49:48
【问题描述】:

我创建了一个函数来过滤和排序列表的内容。

这似乎有点“小”,但 Linq 不是强项。我想知道是否可以从性能角度甚至美学角度简化该功能。

代码如下:

// 反序列化 XML 以创建一类活动行

    var agents = XmlHelper
        .Deserialise<AgentConfigs>("~/Pingtree.xml")
        .Agents
        .Where(x => x.IsActive == true);

// 首先 - 获取“直接”代理并订购它们

    var direct = agents
        .Where(x => x.IsDirect)
        .OrderByDescending(x => x.MinPrice);

// 第二个 - 获取间接代理并对其进行排序

    var agency = agents
        .Where(x => !x.IsDirect)
        .OrderBy(x => x.Priority);

// 将 2 个子列表栓在一起,保持顺序

    Agents = direct.Concat(agency).ToList();

有什么想法可以改进吗?

【问题讨论】:

  • 如果解决方案运行良好,并且您希望改进/审查如何更好地构建它,请发帖至stackoverflow.com/review
  • 首先,您多次迭代相同的枚举,这些枚举由 Resharper 标记,例如这可能会导致性能问题,可以通过在执行进一步查询之前在您的代理上调用 .ToList 轻松避免。
  • @HimBromBeere:OP 直到最后的ToList 才执行查询。由于所涉及的 LINQ 方法的延迟执行的性质,它只枚举一次。您调用ToList 两次的方法会强制对查询进行两次评估。
  • @TimSchmelter 不,我不想在帖子中提到的第一个电话之后打电话给ToList,而不是在其他电话之后。

标签: c# asp.net linq


【解决方案1】:

您可以使用GroupByToLookup 来拆分两者,在这种情况下我更喜欢ToLookup

var activeAgentDirectLookup = XmlHelper
    .Deserialise<AgentConfigs>("~/Pingtree.xml")
    .Agents
    .Where(x => x.IsActive == true)
    .ToLookup(a => a.IsDirect);

Agents = activeAgentDirectLookup[true].OrderByDescending(x => x.MinPrice)
    .Concat(activeAgentDirectLookup[false].OrderBy(x => x.Priority))
    .ToList();

在这种情况下,lookup 类似于以bool 作为键的字典(因此有两个可能的组)。值是IEnumerable&lt;Agents&gt;,所以所有代理都是IsDirect!IsDirect。这样做的好处是您只需要评估一次。

【讨论】:

  • 感谢蒂姆的回复。我对代码有点困惑-请您注释一下这些位的作用。
  • 查找类似于以bool 为键的字典(因此有两个可能的组)。值是IEnumerable&lt;Agents&gt;,因此所有代理都是IsDirect!IsDirect。这样做的好处是您只需要评估一次。
  • 啊,现在得到你 - 很好的解决方案!
猜你喜欢
  • 2023-03-06
  • 2010-10-10
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-11
  • 1970-01-01
相关资源
最近更新 更多