IndexOutOfRangeException при извлечении моделей из хранилища - PullRequest
0 голосов
/ 29 августа 2018

Я получаю это исключение:

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at lambda_method(Closure , ValueBuffer )
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalMixedEntityEntry..ctor(IStateManager stateManager, IEntityType entityType, Object entity, ValueBuffer& valueBuffer)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryFactory.NewInternalEntityEntry(IStateManager stateManager, IEntityType entityType, Object entity, ValueBuffer& valueBuffer)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTrackingFromQuery(IEntityType baseEntityType, Object entity, ValueBuffer& valueBuffer, ISet`1 handledForeignKeys)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityTrackingInfo.StartTracking(IStateManager stateManager, Object entity, ValueBuffer& valueBuffer)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.StartTracking(Object entity, EntityTrackingInfo entityTrackingInfo)
   at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.<>c__DisplayClass18_0`2.<_TrackEntities>b__0(TOut result)
   at System.Linq.AsyncEnumerable.SelectEnumerableAsyncIterator`2.MoveNextCore(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Select.cs:line 109
   at System.Linq.AsyncEnumerable.AsyncIterator`1.MoveNext(CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\AsyncIterator.cs:line 98
   at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext(CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteSingletonAsyncQuery[TResult](QueryContext queryContext, Func`2 compiledQuery, IDiagnosticsLogger`1 logger, Type contextType)
   at SuperChrono.Api.Controllers.UpdateController.GetAsync(Int32 id) in C:\Users\Albert\source\repos\Superchrono 2.0-v2\SuperChrono.Api\Controllers\UpdateController.cs:line 31
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIIndexMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Вот как выглядит UpdateController.GetAsync():

public async Task<IActionResult> GetAsync(int id)
{
    var update = await _updateRepository.GetAsync(id); // 31st line
    if (update == null)
        return NotFound();

    return Ok(new Responses.UpdateResponse { Update = update });
}

Вот хранилище GetAsync():

public Task<Update> GetAsync(int id)
{
    return _db.Updates.FirstOrDefaultAsync(u => u.Id == id);
}

... где _db - мой DbContext. Вот как это выглядит:

public class SuperChronoContext : DbContext
{
    // (...)
    public DbSet<Update> Updates { get; set; }

    public SuperChronoContext(DbContextOptions options)
        : base(options)
    {
        Database.EnsureCreated();
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        // (...)

        builder.Entity<Update>()
            .Property<int>("ProjectId")
            .HasColumnName("id_ProjectNode");
        builder.Entity<Update>()
            .Property<int>("UserId")
            .HasColumnName("id_User");
        builder.Entity<Update>()
            .Property<int>("TypeId")
            .HasColumnName("id_UpdateType");
    }
}

Вот так выглядит модель:

public class Update
{
    [Column("id_Update")]
    public int Id { get; set; }
    [Column("description")]
    public string Description { get; set; }
    /// <summary>
    /// Duration of work on update in minutes.
    /// </summary>
    [Column("usedTime"), Required]
    public int Time { get; set; }
    /// <summary>
    /// Additional duration of work on update in minutes.
    /// </summary>
    [Column("additionalTime"), Required]
    public int AdditionalTime { get; set; }
    [Column("updateDate", TypeName = "smalldatetime"), Required]
    public DateTime Date { get; set; }
    [Column("creationDate", TypeName = "smalldatetime"), Required]
    public DateTime CreatedAt { get; set; }

    [Column("id_ProjectNode"), Required]
    public int ProjectId { get; set; }
    //public virtual Project Project { get;set; }
    [Column("id_User"), Required]
    public int OwnerId { get; set; }
    public virtual User Owner { get; set; }
    [Column("id_UpdateType"), Required]
    public int TypeId { get; set; }
    //public virtual ProjectType Type { get; set; }
}

И, наконец, вот как выглядит мой стол:

table structure


И я не знаю, где моя проблема. Я пробовал решения, которые нашел в Интернете, но они просто не помогли.

У меня есть другие модели в моем коде, и они прекрасно работают. Весь код, извлекающий эти модели из базы данных, выдает мне эту ошибку, не только GetAsync(int id), но и некоторые другие, которые _db.Updates.ToListAsync().

Юнит-тесты с использованием InMemoryDatabase проходят отлично.

Я борюсь с этим уже второй день.

1 Ответ

0 голосов
/ 29 августа 2018

В вашем OnModelCreating вы заявляете:

builder.Entity<Update>()
            .Property<int>("UserId")
            .HasColumnName("id_User");

Но в вашем Update классе у вас есть:

[Column("id_User"), Required]
public int OwnerId { get; set; }

UserId не является собственностью вашей модели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...