LINQ - 将SelectMany嵌套为查询语法

时间:2014-11-26 10:34:49

标签: c# vb.net linq

我有以下工作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函数应用于那些嵌套列表。

到目前为止我已经

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#语法感到满意)

取值

1 个答案:

答案 0 :(得分:0)

我相信你需要的是:

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时我使用了经验法则:如果您的内联查询过于复杂,请将其与不同的方法分开。唯一的例外是针对不接受外部代码的IQueryable API,例如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);

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