使用 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 查询中使用。
也就是说,使用多步骤方法作为折衷方案可能是值得的:
- 使用LINQ限制要搜索的日志文件,
- 阅读文件并
- 使用 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 提供程序。
我存储的内容基本上相当于存储在 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 查询中使用。
也就是说,使用多步骤方法作为折衷方案可能是值得的:
- 使用LINQ限制要搜索的日志文件,
- 阅读文件并
- 使用 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 提供程序。