InvalidCastException в MySqlConnector, а Math.Round внутри LINQ-to-Entities

У меня есть вопрос, на который я пока не могу ответить сам. Проблема возникла в реальном сценарии, но я упростил ее для вопроса. Я просто хотел сделать округление внутри Select в LINQ. Возможно, это следует сделать по-другому?

Следующий код работает как положено:

var test = Math.Round(99.00000000000000000000000000m, 3); // 99.000m
var testLinq1 = new System.Collections.Generic.List<string>() { "dummy" }
    .Select(r => new
    {
        value = Math.Round(99.00000000000000000000000000m, 3) // 99.000m
    })
    .ToList();

Но обе эти строки выдают исключение:

var testLinq2 = _dbContext.SomeEntity
    .Select(r => new
    {
        value = Math.Round(99.00000000000000000000000000m) // Throws an exception.
    })
    .ToList();

var testLinq3 = _dbContext.SomeEntity
    .Select(r => new
    {
        value = Math.Round(99.00000000000000000000000000m, 3) // Throws an exception.
    })
    .ToList();

Исключение составляет:

Исключение типа "System.InvalidCastException" произошло в Microsoft.EntityFrameworkCore.dll, но не было обработано в коде пользователя

Дополнительная информация: Невозможно привести объект типа 'System.Int64' к типу 'System.Decimal'.

InnerException: ноль

Источник: MySqlConnector

StackTrace - это:

at MySql.Data.MySqlClient.MySqlDataReader.GetDecimal(Int32 ordinal)
at lambda_method(Closure , DbDataReader )
at Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create(DbDataReader dataReader)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable.Enumerator.BufferlessMoveNext(Boolean buffer)
at Microsoft.EntityFrameworkCore.Query.QueryMethodProvider.<_ShapedQuery>d__3`1.MoveNext()
at Microsoft.EntityFrameworkCore.Query.Internal.MySqlQueryingEnumerable`1.MySqlEnumerator.MoveNext()
at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at ProjectName.Controllers.SomeController.SomeAction(Int32 propertyId) in D:\Work\Project\ProjectName\Controllers\SomeController.cs:line 419
at lambda_method(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionFilterAsync>d__28.MoveNext()

Это

"Microsoft.NETCore.App": {
  "version": "1.0.1",
  "type": "platform"
}

А я пользуюсь

"Microsoft.EntityFrameworkCore": "1.1.1",
"Pomelo.EntityFrameworkCore.MySql": "1.1.1"

Обновить

Благодаря Тиму Шмелтеру теперь очевидно, что в первом случае это Linq-to-Objects, а во втором - Linq-to-Entities, а Math.Round переводится в SQL. Учитывая постановку вопроса, это можно даже считать ответом. Но мне любопытно, чисто гипотетически, что если я захочу использовать функцию округления MySQL-сервера? Почему этот код прекрасно работает с SQL Server Compact DB, как сказал Джеймс Керран, но не работает с MySQL? Похоже на ошибку разъема.

0 ответов

Другие вопросы по тегам