【问题标题】:Why is the query operator 'ElementAt' is not supported in LINQ to SQL?为什么 LINQ to SQL 不支持查询运算符“ElementAt”?
【发布时间】:2011-07-06 02:07:00
【问题描述】:

在 LINQ to SQL 中,当尝试对从 LINQ to SQL 查询返回的 IQueryable 使用 ElementAt 扩展方法时,出现异常“不支持查询运算符 'ElementAt'。”。

这是堆栈跟踪:

at System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc)
   at System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc)
   at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
   at System.Data.Linq.SqlClient.QueryConverter.ConvertOuter(Expression node)
   at System.Data.Linq.SqlClient.SqlProvider.BuildQuery(Expression query, SqlNodeAnnotations annotations)
   at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
   at System.Data.Linq.Table`1.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.ElementAt[TSource](IQueryable`1 source, Int32 index)

现在我意识到要摆脱这个异常并使用 ElementAt,我可以在使用扩展方法之前调用“.ToList()”,它会起作用。这很好,但我仍然不喜欢这是一个运行时异常(以及看起来像是违反 LSP)的事实。

不支持这些方法有什么原因吗?仅仅是因为它们不能轻易地翻译成 SQL 吗?不支持其他哪些 IQueryable/IEnumerable 扩展方法,是否有列表?

最好避免运行时异常。

【问题讨论】:

  • 不知道他们为什么没有实现它,但你最好使用 .Skip(n - 1).FirstOrDefault() 而不是 .ToList(),因为这些概念将转化为一个 SQL 查询,而不是要求将整个结果集加载到本地机器上
  • 是的,我想我将使用 Skip(n - 1).FirstOrDefault() 而不是 .ToList(),谢谢!

标签: c# linq-to-sql extension-methods


【解决方案1】:

来自 MSDN,Standard Query Operator Translation (LINQ to SQL) - 本文包含尚未翻译的运算符的完整列表:

  • TakeWhile , SkipWhile
  • 反向
  • Last , LastOrDefault
  • ElementAt , ElementAtOrDefault
  • DefaultIfEmpty

没有翻译的运算符

以下方法不 由 LINQ 转换为 SQL。最多 共同的原因是差异 在无序多集和 序列。

运营商

基本原理

...

ElementAt , ElementAtOrDefault

SQL 查询在多重集上运行,而不是 在可索引序列上。

【讨论】:

  • 嗯...有趣,我想这很有道理。 Skip(n).First() 更能代表实际发生的事情......类似于为什么我总是讨厌在 IEnumerable 上使用 .Count() 扩展名(不介意在 IQueryable 上使用它,但是我认为它不应该出现在 IEnumerable 上)
【解决方案2】:

这很奇怪,特别是因为支持Skip()。例如,你能做到吗:

var obj = source.Skip(index).First();

?

【讨论】:

  • 是的,我试过用'.Skip(index).First()',效果很好,我也用过'.Count()'没问题
  • 仅供参考,我必须在 Skip 之前使用 OrderBy()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多