Where 和 Select 的方法链中的 Linq 中间对象?
Linq Intermediate Object in method chain for Where and Select?
我正在处理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。
如果您将 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();
我正在处理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。
如果您将 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();