为了账号安全,请及时绑定邮箱和手机立即绑定

使用 LINQ 查询外部数据源

使用 LINQ 查询外部数据源

C#
慕容3067478 2021-10-24 14:06:47
我存储的内容基本上相当于存储在 CSV 文件中的日志数据。它的格式<datetime>,<val1>,<val2>,等。但是,日志文件按帐户 ID 和月份存储,因此如果您跨月份或帐户 ID 查询,您将检索多个文件。我希望能够使用 LINQ 查询它,这样如果我可以调用logFiles.Where(o => o.Date > 1-1-17 && o.Date < 4-1-17). 我想我需要一些东西来检查该查询中的日期范围,并注意到它跨越 4 个月,然后导致它只检查该日期范围内的文件。有什么方法可以做到这一点,而不涉及使用自定义IQueryable LINQ 提供程序弄脏我的手?如有必要,我可以进入那个兔子洞,但我想首先确保它是正确的兔子洞。
查看完整描述

1 回答

?
守着一只汪

TA贡献1872条经验 获得超3个赞

如果您想在同一Where表达式中同时过滤日志文件名和日志文件内容,我看不到没有自定义IQueryableLINQ 提供程序的解决方案,因为这正是它们的用例:以智能方式访问数据方式基于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 提供程序。


查看完整回答
反对 回复 2021-10-24
  • 1 回答
  • 0 关注
  • 159 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信