LINQ合并多个源的排序

时间:2012-10-10 09:53:45

标签: .net linq extension-methods mergesort

我有几个“数据源”,每个“数据源”提供有序的带时间戳的数据。我想将它压缩成一个有序的流(如合并排序)。 This answer描述了如何为两个枚举执行此操作,但我不确定如何对其进行概括。

数据来源巨大,所以我无法在内存中进行,必须进行流式处理。

用一个例子解释一下,我有这样的事情:

interface IDataSource
{
    IEnumerable<DateTime> GetOrderedRecords();
}

我希望能够有这样的扩展方法:

// get all sources
IEnumerable<IDataSource> dataSources = GetAllSources();

// merge sort
IEnumerable<DateTime> flattened = dataSources
    .MergeSort(s => s.GetOrderedRecords());

[编辑]

我无法急切加载所有内容然后对其进行排序的原因是因为我从多个数据库加载数据并将其导出到另一个数据库中。每个IDataSource基本上都是Linq-to-NHibernate,我要返回数百万个数据行。

所以我需要的是:

  1. 从所有可用来源加载下一个时间戳。
  2. 将其存储到磁盘并“忘记”。
  3. 数据源已经排序,这使得“合并排序”方法可行。

1 个答案:

答案 0 :(得分:2)

您可以做的一件简单事情是从您链接的问题中结束对Merge实现的调用:

public static IEnumerable<DateTime> Merge(this IEnumerable<IDataSource> dataSources)
{
    var result = Enumerable.Empty<DateTime>();

    foreach(var dataSource in dataSources)
    {
        result = result.Merge(dataSource.GetOrderedRecords(), (x, y) => x < y);
    }

    return result;
}

你会这样称呼:

var result = dataSources.Merge();

这样做的缺点是,对返回的枚举的枚举器的每个MoveNext调用都会在嵌套的枚举数上产生大量的MoveNext调用。