使用 LINQ 查询外部数据源

Querying external data source with LINQ

我存储的内容基本上相当于存储在 CSV 文件中的日志数据。它的格式为 <datetime>,<val1>,<val2>, 等。但是,日志文件按帐户 ID 和月份存储,因此如果您跨月或跨帐户 ID 查询,您将检索多个文件。

我希望能够使用 LINQ 查询它,这样我就可以调用 logFiles.Where(o => o.Date > 1-1-17 && o.Date < 4-1-17)。我想我需要一些东西来检查该查询中的日期范围并注意到它跨越 4 个月,然后导致它只检查该日期范围内的文件。

有没有什么方法可以做到这一点,而且不会因为习惯 IQueryable LINQ provider 而弄脏我的手?如有必要,我可以进入那个兔子洞,但我想先确保它是正确的兔子洞。

如果您想在同一个 Where 表达式中同时过滤日志文件名和日志文件内容,我没有看到解决方案 without一个自定义 IQueryable LINQ 提供程序,因为这 正是 他们的用例:基于 表达式 以智能方式访问数据在 LINQ 查询中使用。

也就是说,使用多步骤方法作为折衷方案可能是值得的:

  1. 使用LINQ限制要搜索的日志文件,
  2. 阅读文件并
  3. 使用 LINQ 进行进一步搜索。

示例:

IEnumerable<LogFile> files = LogFiles.Where(f => f.Date > new DateTime(17, 1, 1) && f.AccountID == 4711);
IEnumerable<LogData> data = ParseLogFiles(files);
IEnumerable<LogData> filteredData = data.Where(d => d.val1 == 42 && d.val2 > 17);
LogData firstMatch = filteredData.FirstOrDefault();

如果您实现 ParseLogFiles (a) 延迟执行和 (b) 作为 IEnumerable<LogFile> 上的扩展方法,生成的代码将在外观和感觉上与纯 LINQ 非常相似:

var filteredData = LogFiles.
    Where(f => f.Date > new DateTime(17, 1, 1) && f.AccountID = 4711).
    ParseLogFiles().
    Where(d => d.val == 42 && d.val2 > 17);

// If ParseLogFiles uses deferred execution, the following line won't read
// more log files than required to get the first matching row:
var firstMatch = filteredData.First();

这比在单个 LINQ 查询中完成所有工作要多一些,但它使您不必实施自己的 LINQ 提供程序。