Подтвердить что ты не робот

Неоднозначный вызов IQueryable или IEnumerable

Я создаю контекст и хочу написать простой запрос

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

и я не могу избавиться от красной squiggly в разделе "Где", жалуясь на двусмысленный вызов между System.Collections.Generic.IEnumerable и System.Linq.IQueryable. System.Linq специально ссылается, а System.Collections.Generic не упоминается нигде в проекте. Как я могу указать код, который я хочу использовать System.Linq.IQueryable?

Памела

4b9b3361

Ответ 1

Получил это. Людям, похоже, не нравится этот ответ, но он решил проблему, которую я описал в вопросе.

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

Ответ 2

Эта проблема обычно вызвана сбоем вывода типа из выражения, предоставленного в инструкции Where. Как было упомянуто в комментариях выше, это на 100% вызвано оператором присваивания в лямбда, возвращающим 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;}
}

Затем, если вы выполните следующий запрос, который выглядит очень разумно с первого взгляда, он не сможет скомпилировать с довольно загадочной ошибкой "adiguous invocation"

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

Если вы не пишете это утверждение внутри лямбды, вы получите более значимую ошибку

"Невозможно применить оператор '& &' к операндам типа" System.Nullable <bool> "и" bool"

Что сразу сообщит вам, что вы не возвращаете логическое значение.

Ответ 3

Проблема, которую будет испытывать многие люди, состоит в том, что IQueryable наследует от IEnumerable, и у обоих есть своя реализация различных операторов LINQ.

Ответ Rhys охватывает другую ситуацию, чем эта. Если вы реализуете то, что я говорю ниже, и все еще получаю ошибку, то вы, вероятно, сталкиваетесь с его ситуацией.

Этот ответ показывает различия между IEnumerable и IQueryable. В этой статье объясняется, что подходит для .AsQueryable().

В случае этого конкретного вопроса .AsQueryable() не является правильным способом сделать это, потому что цель в основном заключается в преобразовании IEnumerables в псевдо-запросы. Правильный способ сделать это должен быть явным для компилятора, каков ваш объект.

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

Это говорит компилятору, что dbSet явно, а не пытается выполнить оператор cast, как в случае .AsQueryable().

Добавление var в С# 3.0 было фантастическим для людей, поступающих из свободно типизированных языков, таких как PHP, однако он обманывает людей, думая, что компилятор всегда сможет просто "разобраться". Много раз это не так, и кастинг НЕ является решением.