InvalidCastException in MySqlConnector while Math.Round inside LINQ-to-Entities

Viewed 457

I have a question that I can not answer myself for now. The problem arose in the real scenario, but I simplified it for the question. I just wanted to make the rounding inside Select in LINQ. Perhaps it should be done in another way?

The following code works as expected:

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();

But both of these lines throw an exception:

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();

The exception is:

An exception of type 'System.InvalidCastException' occurred in Microsoft.EntityFrameworkCore.dll but was not handled in user code

Additional information: Unable to cast object of type 'System.Int64' to type 'System.Decimal'.

InnerException: null

Source: MySqlConnector

StackTrace is:

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()

It's

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

And I'm using

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

Update

Thanks to Tim Schmelter it's obvious now that in the first case it's Linq-to-Objects, and in the second case it's Linq-to-Entities and Math.Round is translated to SQL. Given the formulation of the question, this could even be considered an answer. But I'm curious, purely hypothetically, what if I want to use the MySQL server rounding function? Why this code works fine with SQL Server Compact DB, as James Curran said, but it's not working with MySQL? It's looked like a bug of the connector.

0 Answers
Related