0

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

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

有没有什么方法可以做到这一点,而不涉及使用自定义IQueryable LINQ 提供程序弄脏我的手?如有必要,我可以进入那个兔子洞,但我想首先确保它是正确的兔子洞。

4

1 回答 1

1

如果您想在同一个Where表达式中同时过滤日志文件名和日志文件内容,我看不到没有自定义IQueryableLINQ 提供程序的解决方案,因为这正是他们的用例:To access data in a smart方式基于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) 作为扩展方法 on 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 提供程序。

于 2018-07-23T15:41:47.257 回答