LINQ - 嵌套的 SelectMany 作为查询语法

本文关键字:查询 语法 SelectMany 嵌套 LINQ | 更新日期: 2023-09-27 18:31:58

我有以下工作 LINQ 表达式,我想将其转换为查询语法以提高可读性

Dim statements = itemGroups.Select(Function(ig) ig.LinkedItems.SelectMany(Function(i) RefreshItem(i, GetTable(i.EventKey, targetTable)).Statements) _
                                                              .MergeUpdates) _
                           .SelectMany(Function(u) u)

正如您可能看到的那样,我已经嵌套了IEnumerables,但是我想在展平整个内容之前将MergeUpdates函数展平并将MergeUpdates函数应用于这些嵌套列表。

到目前为止,我有

Dim sl = From ig In itemGroups
         From i In ig.LinkedItems
         From s in RefreshItem(i, GetTable(i.EventKey, targetTable)).Statements
         Select s

但我不确定如何使用查询语法展平和合并嵌套的 IEnumerables。

感谢任何帮助。

(顺便说一句 - 我对 VB 或 C# 语法感到满意)

S

LINQ - 嵌套的 SelectMany 作为查询语法

我相信

你需要的是:

var statements =
    from itemsGroup in itemGroups
    from linkedItemStatements in
        //here goes a nested query
        (from linkedItem in itemsGroup.LinkedItems
            let table = GetTable(linkedItem, targetTable)
            select RefreshItem(linkedItem, table).Statements)
        .MergeUpdates()
    from statement in linkedItemStatements
    select statement;

但是,我看不出它如何更具可读性。我在使用 LINQ 时使用经验法则:如果内联查询过于复杂,请将其分隔为不同的方法。唯一的例外是针对不接受外部代码的 API IQueryable例如 LINQ to Entities。

所以我会做这样的事情:

private static IEnumerable<IEnumerable<Statement>> GetMergedItemStatements(
    ItemGroup itemsGroup,
    DataTable targetTable)
{
    var statements =
        from linkedItem in itemsGroup.LinkedItems
        let table = GetTable(linkedItem, targetTable)
        select RefreshItem(linkedItem, table).Statements;
    return statements.MergeUpdates();
}

然后:

var statements =
    from itemsGroup in itemGroups
    from linkedItemStatements in GetMergedItemStatements(itemsGroup, targetTable)
    from statement in linkedItemStatements
    select statement;

使用扩展方法看起来也不错:

private static IEnumerable<IEnumerable<Statement>> GetMergedItemStatements(
    ItemGroup itemsGroup,
    DataTable targetTable)
{
    var mergedStatements = itemsGroup
        .LinkedItems
        .Select(linkedItem =>
            RefreshItem(linkedItem, GetTable(linkedItem, targetTable)).Statements)
        .MergeUpdates();
    return mergedStatements;
}

和:

var statements = itemGroups
    .SelectMany(itemsGroup => GetMergedItemStatements(itemsGroup, targetTable))
    .SelectMany(mergeStatements => mergeStatements);

因此,选择您认为最具可读性的选项。