关于linq:不明确的调用IQueryable或IEnumerable

Ambiguous Invocation IQueryable or IEnumerable

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

1
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


这个问题通常是由提供给WHERE语句的表达式中的类型推断失败引起的。正如上面的注释中所提到的,100%是由于lambda中的赋值运算符返回了int,而不是bool

说清楚-你在哪里

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

你应该拥有

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

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

1
2
3
4
5
public class Elem
{
    public bool IsSomething {get;set;}                    
    public bool? IsSomethingElse {get;set;}
}

然后,如果您执行下面的查询,乍一看这看起来非常合理,那么它将无法编译,并出现令人费解的错误"abigous invocation"。

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

如果不在lambda中编写此语句,则会得到一个更具意义的错误

"Cannot apply operator '&&' to operands of type 'System.Nullable' and 'bool'"

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


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

里斯的回答涵盖了另一种情况。如果你实现了我下面所说的,并且仍然收到错误,那么你很可能遇到了他的情况。

这个答案显示了IEnumerable和IQueryable之间的区别。本文解释了.AsQueryable()的作用。

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

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

这告诉编译器什么是dbset,而不是像在.AsQueryable()的情况下那样试图执行一个cast语句。

在C 3.0中添加var对于来自松散类型语言(如PHP)的人来说是非常好的,但是它会愚弄人们认为编译器总是能够"解决问题"。很多时候情况并非如此,铸造不是解决方案。


我遇到了这个问题——在我的例子中,模型是在一个独立于调用代码的项目中。调用代码没有对ef的引用。在调用项目时添加对ef的引用,为我修复了它。


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

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