方法链中的Linq中间对象在哪里和选择?

Posted

技术标签:

【中文标题】方法链中的Linq中间对象在哪里和选择?【英文标题】:Linq Intermediate Object in method chain for Where and Select? 【发布时间】:2020-11-20 17:26:39 【问题描述】:

我正在处理 DocumentFormat.xml。

我需要做一些工作以获取 where 子句所需的数据。

但是我需要在 where 子句中做同样的工作来构造所需的对象。

这似乎很浪费。

有没有更好的方法来构建它?

var rowData = registersRows
    .Where(row =>
    
        var cells = row.Elements<Cell>().ToList();
        return included.Contains(GetCellText(cells, "A", row.RowIndex, sharedStringTableItems));
    )
    .Select(row =>
    
        var cells = row.Elements<Cell>().ToList();
        return new RegistersRow
        
            StoreNumber = GetCellText(cells, "A", row.RowIndex, sharedStringTableItems),
            ChannelName = GetCellText(cells, "D", row.RowIndex, sharedStringTableItems),
            ChannelDisplayName = GetCellText(cells, "E", row.RowIndex, sharedStringTableItems),
            PhysicalDeviceName = GetCellText(cells, "F", row.RowIndex, sharedStringTableItems),
            FriendlyName = GetCellText(cells, "G", row.RowIndex, sharedStringTableItems),
            DisplayNameInLabel = GetCellText(cells, "H", row.RowIndex, sharedStringTableItems),
            NumberOfRegisters =
                int.Parse(GetCellText(cells, "K", row.RowIndex, sharedStringTableItems))
        ;
    ).ToList();

具体在这个例子中我需要提取StoreNumber并获取Cells两次。

【问题讨论】:

我没有遵循“在 where 子句中”?您的意思是在“Select” lambda 中吗? 是的,从WHERE函数到SELECT函数,换句话说就是传递WHERE函数的中间结果,这样SELECT函数就不必做同样的工作了。跨度> 【参考方案1】:

如果您将 LINQ 与查询语法结合使用,则您可以使用 let 关键字创建一个临时的,以便稍后在查询中使用。当编译器将查询语法转换为 fluent/lambda 语法时,let 将转换为 Select,它将临时值与您需要携带到未来方法中的任何值捆绑在一起。

您可以手动执行相同的操作:

var rowData = registersRows
    .Select(r => new  RowIndex = r.RowIndex, cells = r.Elements<Cell>().ToList() )
    .Select(rc => new  rc.RowIndex, rc.cells, A = GetCellText(rc.cells, "A", rc.RowIndex, sharedStringTableItems) )
    .Where(rca => included.Contains(rca.A))
    .Select(rca => new RegistersRow 
        StoreNumber = rca.A,
        ChannelName = GetCellText(rca.cells, "D", rca.RowIndex, sharedStringTableItems),
        ChannelDisplayName = GetCellText(rca.cells, "E", rca.RowIndex, sharedStringTableItems),
        PhysicalDeviceName = GetCellText(rca.cells, "F", rca.RowIndex, sharedStringTableItems),
        FriendlyName = GetCellText(rca.cells, "G", rca.RowIndex, sharedStringTableItems),
        DisplayNameInLabel = GetCellText(rca.cells, "H", rca.RowIndex, sharedStringTableItems),
        NumberOfRegisters =
                int.Parse(GetCellText(rca.cells, "K", rca.RowIndex, sharedStringTableItems))
    )
    .ToList();

【讨论】:

这是一个很好的思考方式。谢谢!

以上是关于方法链中的Linq中间对象在哪里和选择?的主要内容,如果未能解决你的问题,请参考以下文章

在按属性选择时,后代中的XML到Linq元素会出现对象引用错误

LINQ - 在 IEnumerable 中选择第二个项目

在 R Shiny 中,当链中的对象被隐藏时,如何维护反应链?

如何使用 LINQ 选择具有最小或最大属性值的对象

Linq:在数据表列中选择值

Linq to entity 使用“Func”在生成匿名对象的选择语句中创建属性