在 Linq 中将 List 转换为 IQueryable 的问题
Problems with converting List to IQueryable in Linq
编辑
实际上这个问题应该更笼统:How to modify query to DB if Linq with IQueryable
gives errors?
据我所知,正确答案是在数据库级别完成尽可能多的查询。因为在这种特殊情况下,我的复杂查询无法从 Linq 转换为 sql.
所以我刚刚用 FromSqlRaw()
方法写了一个原始的 sql 查询,错误消失了。此外,与 ToList()
方法相反,我以不获取所有条目(带过滤)的方式编写查询,因此我对性能的怀疑较少(尽管我没有测量它)。
需要一些帮助来理解如何使用 linq 将 List
转换为 IQueryable
。
我有:
数据库中的三个 table 对其中之一进行基于 IQueryable 的查询。
我需要什么:
创建一个查询,通过 Linq 组合来自三个 table 的数据,并给我生成的特定列,其中包含 table 之一的每个元素的数据,并具有按此列过滤的功能。
我尝试的是:
补充基于 IQueryable 的查询。但是我发现 List
到 IQueryable
的转换有问题。方法 AsQueryable()
出错。
我取得的成就:
我在 Linq 中使用基于列表的逻辑重写了查询,它提供了我需要的东西。但是我不明白:
- 这种做法好吗?
- 为什么我必须经常
ToList()
转换以避免错误?
- 我的解决方案的速度是否比基于 IQueryable 的方法差?
这是 fiddle 我的练习:https://dotnetfiddle.net/BAKi6r
我需要的我在 listF
var.
中得到
我将其中的 CreateAsync
方法完全替换为 List
的 Create
方法。好吗?
我还尝试将硬编码列表与 CreateAsync
方法/items2moq
、items3moq
/ 一起使用,但它们与基于过滤列表的查询一起使用会给出 The provider for the source IQueryable doesn't implement IAsyncQueryProvider
错误。当我对 NamesIQ
使用 IQueryable
而不是对 NamesList
使用 List
时,我也遇到了 Argument types do not match
错误。这个错误的确切来源是什么?
Why should I often must make ToList() conversion for avoiding errors?
我经常在三个“级别”中思考 Linq 查询:
IQueryable
- 旨在将 Linq 查询转换为等效的数据库(或您正在使用的任何数据源)查询。许多 Linq 和 non-Linq 操作无法转换为它的 SQL 或其他等价物,因此该层会抛出错误。即使 看起来 简单的操作(如拆分字符串)在 SQL
中即使不是不可能也很难做到
IEnumerable
- 在此层中,Linq 查询在内存中完成,因此执行自定义操作具有更大的灵活性。从IQueryable
层到IEnumerable
层,AsEnumerable()
调用是最直接的。这将获取原始数据的查询部分与可以创建自定义对象、进行更复杂的过滤和聚合等的部分分开。请注意,IEnumerable
仍然使用“延迟执行”,这意味着在这个阶段,查询 只是一个查询 - 结果实际上不会得到计算,直到您 枚举 它,使用 foreach
循环或前进到下一层:
List
/Array
/等等。这是执行查询并将其转换为具体集合的地方。该层的一些好处是可序列化(您不能“序列化”枚举器)和 eager-loading(与上述延迟执行相反)。
所以你 可能 收到错误,因为你的查询的某些部分无法由基础 Queryable
提供商翻译,并且使用 ToList
是一种将原始数据具体化为列表的便捷方式,它允许您进行更复杂的操作。不,AsEnumerable()
会做同样的事情,但会保持延迟执行。
Is this practice good?
可以,但是通过在列表级别而不是数据库级别进行过滤,您可能很容易获得比您需要更多的数据。我的一般做法是在数据库级别完成尽可能多的查询,只有在没有已知方法将其余查询转换为 SQL.[=25 时才移动到 enumrerable/list 级别=]
Is the speed of my solution worse than IQueryable-based approach?
了解的唯一方法是尝试两种方式并衡量差异。但可以肯定的是,如果您获得的原始数据比您需要的多,并且在内存中进行过滤,那么您的性能会更差。
编辑
实际上这个问题应该更笼统:How to modify query to DB if Linq with IQueryable
gives errors?
据我所知,正确答案是在数据库级别完成尽可能多的查询。因为在这种特殊情况下,我的复杂查询无法从 Linq 转换为 sql.
所以我刚刚用 FromSqlRaw()
方法写了一个原始的 sql 查询,错误消失了。此外,与 ToList()
方法相反,我以不获取所有条目(带过滤)的方式编写查询,因此我对性能的怀疑较少(尽管我没有测量它)。
需要一些帮助来理解如何使用 linq 将 List
转换为 IQueryable
。
我有: 数据库中的三个 table 对其中之一进行基于 IQueryable 的查询。
我需要什么: 创建一个查询,通过 Linq 组合来自三个 table 的数据,并给我生成的特定列,其中包含 table 之一的每个元素的数据,并具有按此列过滤的功能。
我尝试的是:
补充基于 IQueryable 的查询。但是我发现 List
到 IQueryable
的转换有问题。方法 AsQueryable()
出错。
我取得的成就: 我在 Linq 中使用基于列表的逻辑重写了查询,它提供了我需要的东西。但是我不明白:
- 这种做法好吗?
- 为什么我必须经常
ToList()
转换以避免错误? - 我的解决方案的速度是否比基于 IQueryable 的方法差?
这是 fiddle 我的练习:https://dotnetfiddle.net/BAKi6r
我需要的我在 listF
var.
我将其中的 CreateAsync
方法完全替换为 List
的 Create
方法。好吗?
我还尝试将硬编码列表与 CreateAsync
方法/items2moq
、items3moq
/ 一起使用,但它们与基于过滤列表的查询一起使用会给出 The provider for the source IQueryable doesn't implement IAsyncQueryProvider
错误。当我对 NamesIQ
使用 IQueryable
而不是对 NamesList
使用 List
时,我也遇到了 Argument types do not match
错误。这个错误的确切来源是什么?
Why should I often must make ToList() conversion for avoiding errors?
我经常在三个“级别”中思考 Linq 查询:
中即使不是不可能也很难做到IQueryable
- 旨在将 Linq 查询转换为等效的数据库(或您正在使用的任何数据源)查询。许多 Linq 和 non-Linq 操作无法转换为它的 SQL 或其他等价物,因此该层会抛出错误。即使 看起来 简单的操作(如拆分字符串)在 SQLIEnumerable
- 在此层中,Linq 查询在内存中完成,因此执行自定义操作具有更大的灵活性。从IQueryable
层到IEnumerable
层,AsEnumerable()
调用是最直接的。这将获取原始数据的查询部分与可以创建自定义对象、进行更复杂的过滤和聚合等的部分分开。请注意,IEnumerable
仍然使用“延迟执行”,这意味着在这个阶段,查询 只是一个查询 - 结果实际上不会得到计算,直到您 枚举 它,使用foreach
循环或前进到下一层:List
/Array
/等等。这是执行查询并将其转换为具体集合的地方。该层的一些好处是可序列化(您不能“序列化”枚举器)和 eager-loading(与上述延迟执行相反)。
所以你 可能 收到错误,因为你的查询的某些部分无法由基础 Queryable
提供商翻译,并且使用 ToList
是一种将原始数据具体化为列表的便捷方式,它允许您进行更复杂的操作。不,AsEnumerable()
会做同样的事情,但会保持延迟执行。
Is this practice good?
可以,但是通过在列表级别而不是数据库级别进行过滤,您可能很容易获得比您需要更多的数据。我的一般做法是在数据库级别完成尽可能多的查询,只有在没有已知方法将其余查询转换为 SQL.[=25 时才移动到 enumrerable/list 级别=]
Is the speed of my solution worse than IQueryable-based approach?
了解的唯一方法是尝试两种方式并衡量差异。但可以肯定的是,如果您获得的原始数据比您需要的多,并且在内存中进行过滤,那么您的性能会更差。