【问题标题】:Problems with converting List to IQueryable in Linq [closed]在 Linq 中将 List 转换为 IQueryable 的问题[关闭]
【发布时间】:2020-11-24 15:07:58
【问题描述】:

编辑

其实这个问题应该更笼统:How to modify query to DB if Linq with IQueryable 报错?

据我所知,正确的答案是在数据库级别完成尽可能多的查询。因为在这种特殊情况下,我的复杂查询无法从 Linq 转换为 sql。

所以我刚刚用FromSqlRaw() 方法编写了一个原始的sql 查询,错误就消失了。此外,我以不采用所有条目(带有过滤)的方式编写查询,而不是 ToList() 方法,因此我对性能的怀疑较少(尽管我没有测量它)。


在了解如何使用 linq 将 List 转换为 IQueryable 时需要一些帮助。

我有什么: DB 中的三个表,其中一个具有基于 IQueryable 的查询。

我需要什么: 创建一个查询,通过 Linq 组合来自三个表的数据,并为我提供一个带有按此列过滤功能的表的每个元素的数据的特定列。

我的尝试: 补充基于 IQueryable 的查询。但我发现ListIQueryable 的转换存在问题。方法AsQueryable() 报错。

我的成就: 我在 Linq 中使用基于列表的逻辑重写查询,它给了我我需要的东西。但我不明白:

  • 这种做法好吗?
  • 为什么我必须经常进行ToList() 转换以避免错误?
  • 我的解决方案的速度是否比基于 IQueryable 的方法更差?

这是我的练习:https://dotnetfiddle.net/BAKi6r

我需要什么我得到listF var。

我将其中的 CreateAsync 方法完全替换为 ListCreate 方法。好吗? 我还尝试使用带有CreateAsync 方法/items2moqitems3moq/ 的硬编码列表,但它们使用过滤后的基于列表的查询会给出The provider for the source IQueryable doesn't implement IAsyncQueryProvider 错误。当我使用IQueryable 代替NamesIQ 而不是List 代替NamesList 时,我也得到了Argument types do not match 错误。这个错误的确切来源是什么?

【问题讨论】:

标签: c# linq iqueryable


【解决方案1】:

为什么我必须经常进行 ToList() 转换以避免错误?

我经常将 Linq 查询分为三个“级别”:

  1. IQueryable - 旨在将 Linq 查询转换为等效的数据库(或您正在使用的任何数据源)查询。许多 Linq 和非 Linq 操作无法转换成其 SQL 或其他等效操作,因此这一层会抛出错误。即使是看起来简单的操作(比如拆分字符串)在 SQL 中也很难做到,如果不是不可能的话

  2. IEnumerable - 在这一层中,Linq 查询在内存中完成,因此可以更灵活地进行自定义操作。要从IQueryable 层到IEnumerable 层,AsEnumerable() 调用是最直接的。这将获取原始数据的查询部分与可以创建自定义对象、进行更复杂的过滤和聚合等的部分分开。请注意,IEnumerable 仍然使用“延迟执行”,这意味着在这个阶段,查询是只是一个查询 - 在您枚举它之前,实际上不会计算结果,无论是使用foreach 循环还是前进到下一层:

  3. List/Array/等。这是执行查询并将其转换为具体集合的地方。该层的一些好处是可序列化(您不能“序列化”枚举器)和急切加载(与上述延迟执行相反)。

所以您可能遇到错误,因为您的查询的某些部分无法被底层 Queryable 提供程序翻译,而使用 ToList 是一种方便的方法将原始数据具体化为一个列表,这允许您执行更复杂的操作。不知道AsEnumerable() 会做同样的事情,但会保持延迟执行。

这种做法好吗?

可以,但是通过在列表级别而不是在数据库级别进行过滤,您可能很容易获得比您需要的更多的数据。我的一般做法是在数据库级别完成尽可能多的查询,并且只有在没有已知方法将查询的其余部分转换为 SQL 时才移动到可枚举/列表级别。

我的解决方案的速度是否比基于 IQueryable 的方法更差?

知道的唯一方法是尝试两种方法并衡量差异。但可以肯定的是,如果您获得的原始数据比您需要的多,并且在内存中进行过滤,那么您的性能会更差。

【讨论】:

    猜你喜欢
    • 2020-04-23
    • 2015-07-12
    • 2012-11-15
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 2010-11-18
    • 2021-01-14
    • 1970-01-01
    相关资源
    最近更新 更多