Невозможно привести объект типа 'System.String' к типу 'System.DateTime' в литерале datetime. - PullRequest
2 голосов
/ 26 сентября 2019

У нас есть база данных MySQL хостов игр, которая может запускать игры определенного набора типов игр.У меня есть оператор linq, который возвращает идентификатор хоста, имя и заголовок + время начала последней игры, сыгранной на хосте (если есть).

context.HostConfigurations.Select (h => new HostStatus {
                id = h.IdHostConfigurations,
                hostname = h.Hostname,
                gameTitle = h.IdGamesLast.HasValue ? h.LastGameNavigation.GameTypeNavigation.Title : "-",
                gameStart = h.IdGamesLast.HasValue ? h.LastGameNavigation.Gamestart : DateTimeOffset.MinValue,
                gameStartFriendly = h.IdGamesLast.HasValue ? h.LastGameNavigation.Gamestart.ToString ("ddd HH:mm") : "-"
            }).ToList ();

Вывести журнал следующим образом:

INFO: Microsoft.EntityFrameworkCore.Database.Command Executed DbCommand (21ms) [Parameters=[@__nowMinus24Hrs_0='?' (DbType = DateTimeOffset), @__nowMinusTenMinutes_1='?' (DbType = DateTimeOffset)], CommandType='Text', CommandTimeout='30']
SELECT `h`.`idHostConfigurations` AS `id`, `h`.`hostname`, CASE
    WHEN `h`.`idGamesLast` IS NOT NULL
    THEN `h.LastGameNavigation.GameTypeNavigation`.`title` ELSE '-'
END AS `gameTitle`, CASE
    WHEN `h`.`idGamesLast` IS NOT NULL
    THEN `h.LastGameNavigation`.`gamestart` ELSE '0001-01-01 00:00:00.000000'
END AS `gameStart0`, CASE
WHEN `h`.`idGamesLast` IS NOT NULL
    THEN TRUE ELSE FALSE
END, `h.LastGameNavigation`.`gamestart`
FROM `HostConfigurations` AS `h`
LEFT JOIN `Games` AS `h.LastGameNavigation` ON `h`.`idGamesLast` = `h.LastGameNavigation`.`idGames`
LEFT JOIN `GameTypes` AS `h.LastGameNavigation.GameTypeNavigation` ON `h.LastGameNavigation`.`idGameTypes` = `h.LastGameNavigation.GameTypeNavigation`.`idGameTypes`

ERROR: Microsoft.EntityFrameworkCore.Query An exception occurred while iterating over the results of a query for context type '...'.
System.InvalidCastException: Unable to cast object of type 'System.String' to type 'System.DateTime'.
   at MySqlConnector.Core.Row.GetDateTime(Int32 ordinal) in C:\projects\mysqlconnector\src\MySqlConnector\Core\Row.cs:line 285
   at MySqlConnector.Core.Row.GetDateTimeOffset(Int32 ordinal) in C:\projects\mysqlconnector\src\MySqlConnector\Core\Row.cs:line 288
   at MySql.Data.MySqlClient.MySqlDataReader.GetFieldValue[T](Int32 ordinal) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 261
   at lambda_method(Closure , DbDataReader )
   at Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create(DbDataReader dataReader)
   at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.BufferlessMoveNext(DbContext _, Boolean buffer, CancellationToken cancellationToken)
   at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable`1.AsyncEnumerator.MoveNext(CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)

Если я закомментирую строку 'gameStart = ...' из лямбда-метода, исключений не будет.Очевидно, это потому, что литерал datetime для MinValue интерпретируется как строка в наборе результатов.Это похоже на серьезное ограничение коннектора MySQL?

Любые идеи для обходного пути высоко ценятся!

Ответы [ 2 ]

1 голос
/ 26 сентября 2019

Есть обходной путь.Вы можете объявить минимальную переменную даты как DateTimeOffset? min = DateTimeOffset.MinValue и использовать ее в запросе.

context.HostConfigurations.Select (h => new HostStatus {
            id = h.IdHostConfigurations,
            hostname = h.Hostname,
            gameTitle = h.IdGamesLast.HasValue ? h.LastGameNavigation.GameTypeNavigation.Title : "-",
            gameStart = h.IdGamesLast.HasValue ? h.LastGameNavigation.Gamestart : min ,
            gameStartFriendly = h.IdGamesLast.HasValue ? h.LastGameNavigation.Gamestart.ToString ("ddd HH:mm") : "-"
        }).ToList ();
0 голосов
/ 26 сентября 2019

На данный момент я нашел обходной путь для проблемы соединителя путем принудительной локальной оценки выражения:

        var hosts = await context.HostConfigurations.Include (h => h.LastGameNavigation).ThenInclude (lg => lg.GameTypeNavigation).ToListAsync ();

        var l = new List<HostStatus> ();

        hosts.ForEach (h => {
            l.Add (new HostStatus {
                id = h.IdHostConfigurations,
                hostname = h.Hostname,
                gameTitle = h.IdGamesLast.HasValue ? h.LastGameNavigation.GameTypeNavigation.Title : "-",
                gameStart = h.IdGamesLast.HasValue ? h.LastGameNavigation.Gamestart : DateTimeOffset.MinValue,
                gameStartFriendly = h.IdGamesLast.HasValue ? h.LastGameNavigation.Gamestart.ToString ("ddd HH:mm") : "-",
            });
        });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...