Выделение выражения LINQ вызывает «Внутренняя ошибка поставщика данных .NET Framework 1025.»

Следующий код:

model.Items = dbQuery.Select(c => new Item { Total = c.Items.Count((Func)(t => t.Amount.HasValue)) }).ToArray(); 

Выдает следующее исключение:

Внутренняя ошибка поставщика данных .NET Framework 1025.

Однако точный код за вычетом работ:

 model.Items = dbQuery.Select(c => new Item { Total = c.Items.Count(t => t.Amount.HasValue) }).ToArray(); 

Примечание: dbQuery – это просто объект dbQuery ObjectQuery .

Ожидаемый тип для Count() – это Func , и даже ReSharper проверяет, что они одного типа, потому что он вычеркивает выскакивание, предполагая, что он не нужен, и они функционально эквивалентны.

Однако исключение доказывает, что они фактически не являются функционально эквивалентными.

Кроме того, я видел этот связанный вопрос / ответ , но Count() (в этом случае, во всяком случае) не примет Expression<Func> , так что это не работает для меня.

Вы хотите «сохранить [] выражение в переменной для целей повторного использования и передать это в Count() ». Это на 100% возможно, если Expression можно перевести на SQL. Проблема здесь в том, что вы вводите что-то, что невозможно перевести на SQL. Особая проблема в этом случае заключается в том, что трансляция выполняется в Expression.Convert . Ваши типы определенно не представлены в SQL, поэтому это невозможно выполнить. Подключите оба в LINQPad и проверьте IL, чтобы увидеть разницу.

Поскольку другой связанный с вами вопрос / ответ, который вы связываете с предложениями, вам нужно передать свой предикат как Expression а не Func ( как выполнить работу или указывать на место в коде, который выполняет эту работу). Проблема, как вы заметили, заключается в том, что метод Count не принимает Expression , но это легко разрешается с помощью AsQueryable() который даст вам IQueryable расширения IQueryable которые принимают Expression .

У этого не должно быть никаких проблем:

 Expression> predicate = i => i.Amount.HasValue; model.Items = dbQuery.Select(c => new Item { Total = c.Items.AsQueryable().Count(predicate) }).ToArray(); 

Проблема в том, что поставщик данных не может преобразовать это выражение LINQ в инструкцию SQL. В том, что не работает, граф передается делегату метода. Подумайте, как передать указатель на такой метод, как:

 private static bool MyFunction(Item item) { return item.Amount.HasValue; } 

Теперь проблема заключается в том, что поставщик данных не собирается входить в этот метод, пытаясь выяснить, как превратить его в SQL.

Поставщик данных очень способен пересекать деревья выражений для создания SQL, как работает пример «minus cast», а также связанный ответ, связанный с вашим сообщением.

Если вы можете обновить свое сообщение тем, что вы пытаетесь выполнить, я могу вам помочь.