从存储库检索模型时出现IndexOutOfRangeException

时间:2018-08-29 06:21:48

标签: entity-framework asp.net-core entity-framework-core

我遇到此异常:

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


我不知道我的问题在哪里。我尝试了在Internet上找到的解决方案,但它们无济于事。

我的代码中还有其他模型,它们可以正常工作。从数据库中获取这些模型的所有代码都会引发此错误,不仅是GetAsync(int id),还有其他一些发生_db.Updates.ToListAsync()的错误。

使用InMemoryDatabase通过的单元测试就可以了。

第二天,我为此而苦苦挣扎。

1 个答案:

答案 0 :(得分:1)

在您的OnModelCreating中声明:

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

但是在您的Update类中,您有:

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

UserId不是模型的属性。