【问题标题】:Ambiguous Invocation IQueryable or IEnumerable模糊调用 IQueryable 或 IEnumerable
【发布时间】:2013-11-08 21:59:17
【问题描述】:

我实例化了一个上下文,想写一个简单的查询:

var result = db.Set.Where(x => x.Id == num).Select(whatever);

我无法摆脱Where 下的红色波浪线,抱怨System.Collections.Generic.IEnumerableSystem.Linq.IQueryable. 之间的模棱两可的调用System.Linq 被特别引用,System.Collections.Generic 在项目的任何地方都没有被引用。如何告诉我要使用的代码System.Linq.IQueryable

【问题讨论】:

  • db.Set的类型是什么?
  • 尝试将 = 更改为相等 == :)
  • 请发布准确错误信息。 (我确信 Marcin 是对的,但为了学习提出更好的问题,最好编辑问题以包含错误消息和其他信息。)
  • 如果dbDbContextSet 应该有一个泛型类型参数。

标签: linq entity-framework


【解决方案1】:

此问题通常是由提供给 Where 语句的表达式中的类型推断失败引起的。正如上面的 cmets 中提到的,它 100% 是由 lambda 中的赋值运算符返回 int 而不是 bool 引起的。

要清楚 - 你在哪里

var result = db.Set.Where(x => x.Id = num).Select(whatever);

你应该有

var result = db.Set.Where(x => x.Id == num).Select(whatever);

另一个好的(也是更常见的)例子是这样的

public class Elem 
{
    public bool IsSomething {get;set;}                    
    public bool? IsSomethingElse {get;set;}
}

那么如果你做如下查询,乍一看很合理,它会编译失败并出现“模糊调用”的相当令人费解的错误

IQueryable<Elem> queryable = GetQueryable();
var result = queryable.Where(e => e.IsSomething && e.IsSomethingElse).ToList();

如果您没有在 lambda 中编写此语句,那么您会得到一个更有意义的错误

“不能将运算符'&&'应用于'System.Nullable'和'bool'类型的操作数”

这会立即告诉您您没有返回布尔值。

【讨论】:

  • 是的,错误的 lambda 表达式是这里的罪魁祸首。
  • 我刚刚遇到了另一种情况:在 LINQ 链的中间,在包含方法调用的 Where() 中忘记了 )
【解决方案2】:

知道了。人们似乎不喜欢这个答案,但它解决了我在问题中描述的问题。

db.Set.AsQueryable().Where(...

【讨论】:

  • 什么是db.Set?我不明白你怎么不能使用泛型。看起来确实不太健康。
  • 此解决方案不会对代码进行功能更改,AsQueryable 的实现会测试源是否已经是可查询的 - 如果是,则将其强制转换为 IQueryable 并返回。
  • 它可能不会更改代码,但它消除了导致我的问题的歧义。
  • 尽管投了反对票,但这个答案解决了我的红色波浪形问题。
  • 这不应该是公认的答案。问题是在 where 表达式中使用了赋值运算符 '=' 而不是等式运算符 '=='。下面的 Rhys Bevilaqua 为将来到达这里的人正确回答了这个问题。
【解决方案3】:

很多人会遇到的问题是因为 IQueryable 继承自 IEnumerable,并且它们都有自己的各种 LINQ 语句的实现。

Rhys 的回答涵盖了另一种情况。如果你执行我下面说的,仍然收到错误,那么你可能遇到了他的情况。

This answer 显示了 IEnumerable 和 IQueryable 之间的区别。 This article 解释了 .AsQueryable() 的用途。

在这个特定问题的情况下,.AsQueryable() 不是这样做的正确方法,因为其目的主要是将 IEnumerables 转换为伪可查询对象。正确的做法是向编译器明确说明你的对象是什么。

IQueryable<whateverSet> dbSet = db.Set;
var result = dbSet.Where(x => x.Id == num).Select(whatever);

这是在明确告诉编译器 dbSet 是什么,而不是像 .AsQueryable() 那样尝试执行强制转换语句。

在 C# 3.0 中添加 var 对于来自 PHP 等松散类型语言的人来说非常棒,但是它使人们误以为编译器总是能够“弄清楚”。很多时候情况并非如此,并且强制转换不是解决方案。

【讨论】:

  • 人们再次错过了他的错误。请注意,他的比较中有一个 = !!!他将 int 返回到表达式,而不是 boolean。另一方面,您已经修复了他的错误并将== 放入。
  • 您的回答是我发现的两种可能导致同样曲折的情况之一,将来找到此线程的人可能看不到它是哪个问题。鉴于 OP 使用 AsQueryable() 选择了他自己的答案,这告诉我他在上面的示例代码中只是有一个错字,而 == 只是一个红鲱鱼,而不是他的问题的原因。这并不意味着你的答案对于其他人的情况是错误的。
  • @JimYarbro 他的回答具体是 OP 的问题提到的问题的原因。如果 OP 打错了他们的问题,那么他们需要修复它,或者接受实际回答问题的答案。
【解决方案4】:

我遇到了这个问题 - 在我的例子中,模型与调用代码位于一个单独的项目中。 调用代码没有对 EF 的引用。 在调用项目中添加对 EF 的引用为我修复了它。

【讨论】:

    【解决方案5】:

    在我的特殊情况下,我遇到了同样的错误,但原因是没有引用 System.Linq。添加引用修复了这种特殊情况下的错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-28
      • 1970-01-01
      • 2011-06-09
      • 1970-01-01
      • 2014-11-09
      • 1970-01-01
      • 2016-10-26
      • 1970-01-01
      相关资源
      最近更新 更多