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? Похоже на ошибку разъема.