【问题标题】:Single Select() statement or multiple for transformation with multiple steps?单个 Select() 语句或多个用于多步骤转换的语句?
【发布时间】:2020-01-18 19:49:44
【问题描述】:

在 C# 中,我有一组要转换为不同类型的对象。我想用 LINQ Select() 进行的这种转换需要按顺序执行多个操作。要执行这些操作,最好将多个Select() 查询链接在一起,例如

resultSet.Select(stepOneDelegate).Select(stepTwoDelegate).Select(stepThreeDelegate);

或者改为在一次调用中执行这三个步骤?

resultSet.Select(item => stepThree(stepTwo(stepOne(item))));

注意:这三个步骤本身是不一定的功能。它们旨在简明扼要地展示问题。如果这对答案有影响,请包含该信息。

【问题讨论】:

  • 简短的回答是——通常没关系。后者的性能可能稍微更好,但ericlippert.com/2012/12/17/performance-rant.
  • 这几乎肯定会因为基于意见而关闭 - 所以我不妨分享我的意见。我更喜欢前者,因为它更好地显示了流程(第 1 步的项目,然后是第 2 步,然后是第 3 步)。另外,您可以通过代码的不同方法完成投影的不同部分(即添加 Select 调用)。但老实说,后者已经足够好了,因为程序员习惯于逆向阅读这些步骤(因为大多数程序代码都是这样编写的)。

标签: c# performance linq optimization query-optimization


【解决方案1】:

任何性能差异都可以忽略不计,但对此的明确答案只是“测试它”。问题将更多地与可读性有关,哪个更容易理解和掌握正在发生的事情。

我需要在 Projection 上进行投影的情况包括使用 EF Linq 表达式时,我最终需要执行 EF Linq 不支持的操作,因此我需要具体化投影(通常是匿名类型)然后在选择最终输出之前完成表达式。在这些情况下,您需要使用第一个示例。

就我个人而言,我可能只是坚持第一种情况,因为它很容易理解发生了什么,并且它很容易支持其他操作的添加,例如使用 Where 过滤或使用 OrderBy 等。第二种情况只有在我构建复合模型时才会真正出现。

.Select(x => new OuterModel
{
   Id = x.Id,
   InnerModel = x.Inner.Select(i => new InnerModel
   {
      // ...
   })
}) // ...

在大多数情况下,这可以通过 Automapper 处理。

我会警惕任何我认为需要链接大量 Select 表达式的代码,因为这听起来像是在一个表达式链中尝试做太多事情。让事情变得易于理解,即使它涉及一些额外的步骤并且可能会增加几毫秒的执行时间,也比冒着需要追踪某人引入的错误的风险要好得多,因为他们可能误解了看起来很复杂的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-27
    • 2016-06-03
    • 2020-06-29
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 2021-01-05
    • 1970-01-01
    相关资源
    最近更新 更多