Ошибка приведения в EF Core при вызове хранимой процедуры на MySQL (с использованием Pomelo) - PullRequest
0 голосов
/ 08 января 2019

У меня проблема с веб-API .Net Core 2.2, использующим EF Core. Я вызываю хранимую процедуру в базе данных MySQL (я использую Pomelo 2.1.4).

Он жалуется на невозможность конвертировать из DbNull в строку:

Ошибка: невозможно привести объект типа 'System.DBNull' к типу 'System.String'. в MySql.Data.MySqlClient.MySqlDataReader.GetString (Int32 порядковый номер) в C: \ Проекты \ mysqlconnector \ SRC \ MySqlConnector \ MySql.Data.MySqlClient \ MySqlDataReader.cs: линия 210 в lambda_method (закрытие, DbDataReader) в Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create (DbDataReader dataReader) в 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 операция, Func 4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable 1.AsyncEnumerator.MoveNext (CancellationToken CancellationToken) в System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator 2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 106<br> at System.Linq.AsyncEnumerable.AsyncIterator 1.MoveNext (CancellationToken CancellationToken) в D: \ а \ 1 \ S \ Ix.NET \ Source \ System.Interactive.Async \ AsyncIterator.cs: линия 98 в Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor 1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken) at System.Linq.AsyncEnumerable.Aggregate_[TSource,TAccumulate,TResult](IAsyncEnumerable 1 источник, TAccumulate seed, Func 3 accumulator, Func 2 resultSelector, CancellationToken) отмена) в D: \ a \ 1 \ s \ Ix.NET \ Source \ System.Interactive.Async \ Aggregate.cs: строка 120 в PropWorx.API.Controllers.FileActivitiesController.GetFileActivities (Int32 fileId, String fromDate, String toDate) в C: \ Users \ fabsr \ Source \ РЕПО \ PropWorx.API \ PropWorx.API \ Контроллеры \ FileActivitiesController.cs: линия 101 в Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute (IActionResultTypeMapper картограф, исполнитель ObjectMethodExecutor, контроллер объекта, объект [] аргументы) в System.Threading.Tasks.ValueTask`1.get_Result () в Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync () в Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync () в Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow (ActionExecutedContext контекст) в Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next (State & затем, Область и область действия, Объект и состояние, Boolean & isCompleted) в Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync () в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter () в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow (ResourceExecutedContext контекст) в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next (State & next, Scope & scope, Object & state, Boolean & isCompleted) в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync () в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync ()
в Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke (HttpContext httpContext) в Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke (HttpContext httpContext) в PropWorx.API.Middlewares.TenantIdentifier.Invoke (HttpContext httpContext, SharedContext sharedContext) в C: \ Users \ fabsr \ Source \ РЕПО \ PropWorx.API \ PropWorx.API \ промежуточное программное \ TenantIdentifier.cs: линия 73 в Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke (HttpContext контекст) в Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke (HttpContext контекст) в Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke (HttpContext контекст) в Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke (HttpContext httpContext) в Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke (HttpContext httpContext, ISwaggerProvider swaggerProvider) в Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke (HttpContext контекст) в Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke (HttpContext контекст)

Строка проблемы:

List<FileActivity> fileActivities = await _context.FileActivities.FromSql("CALL file_activity_procedure(@fromDate, @toDate, @fileId)", param1, param2, param3).ToListAsync();

Модель FileActivity:

public class FileActivity
{
    public int Id { get; set; }
    public DateTime? Date { get; set; }
    public int FileId { get; set; }
    public string FileNumber { get; set; }
    public string Area { get; set; }
    public int? RecordId { get; set; }
    public string Description { get; set; }
    public string Type { get; set; }
    public string TypeInfo { get; set; }
    public decimal? Debit { get; set; }
    public decimal? Credit { get; set; }
    public string AddedBy { get; set; }
    public DateTime? AddedDate { get; set; }
    public string Comments { get; set; }
}

И, наконец, отображение в DbContext:

modelBuilder.Entity<FileActivity>(entity =>
{
    entity.Property(e => e.Id)
        .HasColumnName("ID")
        .HasColumnType("int(11)");

    entity.Property(e => e.Date)
        .HasColumnName("Date")
        .HasColumnType("datetime");

    entity.Property(e => e.FileId)
        .HasColumnName("file_id")
        .HasColumnType("int(11)");

    entity.Property(e => e.FileNumber)
        .IsRequired()
        .HasColumnName("file_num")
        .HasColumnType("varchar(50)");

    entity.Property(e => e.Description)
        .IsRequired()
        .HasColumnName("description")
        .HasColumnType("varchar(255)");

    entity.Property(e => e.Type)
        .HasColumnName("type")
        .HasColumnType("varchar(255)");

    entity.Property(e => e.TypeInfo)
        .HasColumnName("type_info")
        .HasColumnType("varchar(255)");

    entity.Property(e => e.Debit)
       .HasColumnName("Debit")
       .HasColumnType("decimal(13,4)")
       .HasDefaultValueSql("'0.0000'");

    entity.Property(e => e.Credit)
       .HasColumnName("Credit")
       .HasColumnType("decimal(13,4)")
       .HasDefaultValueSql("'0.0000'");

    entity.Property(e => e.RecordId)
       .HasColumnName("record_id")
       .HasColumnType("int(11)");

    entity.Property(e => e.AddedBy)
        .HasColumnName("Added_By")
        .HasColumnType("varchar(45)");

    entity.Property(e => e.AddedDate)
        .HasColumnName("added_date")
        .HasColumnType("datetime");

    entity.Property(e => e.Comments)
        .HasColumnName("comment")
        .HasColumnType("text");
});

Я целый день ломал свой мозг, пытаясь выяснить это ... Есть идеи?

Ответы [ 2 ]

0 голосов
/ 02 августа 2019

Проблема в том, что те свойства, которые не требуются в modelBuilder, должны быть определены как обнуляемые в ваших сущностях и моделях с помощью?. Подобно FileId, и это потому, что если в таблице есть запись с нулевым значением для этих полей, то он вернет нулевое значение в вашем классе сущности, но ваш класс сущности не может принять нулевое значение для этих ненулевых свойств и затем выбрасывает ошибка.

0 голосов
/ 09 января 2019

Как отметил Иван в комментарии, поля "description" и "file_num" были обязательными (IsRequired = true). Поскольку некоторые строки имели DbNulls, это вызвало исключение. Я снял это ограничение, и все было хорошо.

...