IndexOutOfRangeException when retrieving models from repository

asp.net-core entity-framework entity-framework-core

Question

I'm getting this exception:

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)

Here's how UpdateController.GetAsync() looks like:

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

Here's the repository GetAsync():

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

...where _db is my DbContext. That's how it looks:

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");
    }
}

That's how the model looks like:

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; }
}

And finally, here's how my table looks like:

table structure


And I don't know where is my problem. I tried solutions I found on the Internet, but they just didn't help.

I have other models in my code and they work just fine. All code fetching those models from database throws me this error, not only GetAsync(int id) but also some other that does _db.Updates.ToListAsync().

Unit tests using an InMemoryDatabase pass just fine.

I'm struggling with this for the second day now.

1
0
8/29/2018 6:21:48 AM

Accepted Answer

In your OnModelCreating you declare :

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

But in your Update class you have:

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

UserId is not a property of your model.

A good way to avoid this kind of problems in the future is to use .Property(u => u.OwnerId) instead.

1
4/3/2020 1:01:07 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow