【问题标题】:Linq Intermediate Object in method chain for Where and Select?方法链中的Linq中间对象在哪里和选择?
【发布时间】: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函数就不必做同样的工作了。跨度>

标签: c# linq linq-to-objects


【解决方案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();

【讨论】:

  • 这是一个很好的思考方式。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 1970-01-01
  • 1970-01-01
  • 2018-03-11
相关资源
最近更新 更多