Open uladz-zubrycki opened 3 years ago
Note for triage:
Unhandled exception. System.NotSupportedException: Collection was of a fixed size.
at System.SZArrayHelper.Remove[T](T value)
at Microsoft.EntityFrameworkCore.Metadata.Internal.ClrICollectionAccessor`3.Remove(Object entity, Object value)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.RemoveFromCollection(INavigation navigation, InternalEntityEntry value)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.RemoveFromCollection(InternalEntityEntry entry, INavigation navigation, InternalEntityEntry value)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.KeyPropertyChanged(InternalEntityEntry entry, IProperty property, IReadOnlyList`1 containingPrincipalKeys, IReadOnlyList`1 containingForeignKeys, Object oldValue, Object newValue)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.KeyPropertyChanged(InternalEntityEntry entry, IProperty property, IReadOnlyList`1 keys, IReadOnlyList`1 foreignKeys, Object oldValue, Object newValue)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.DetectKeyChange(InternalEntityEntry entry, IProperty property)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ChangeDetector.PropertyChanged(InternalEntityEntry entry, IPropertyBase propertyBase, Boolean setModified)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.PropertyChanged(InternalEntityEntry entry, IPropertyBase property, Boolean setModified)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetProperty(IPropertyBase propertyBase, Object value, Boolean isMaterialization, Boolean setModified, Boolean isCascadeDelete, CurrentValueType valueType)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetTemporaryValue(IProperty property, Object value, Boolean setModified)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.SetForeignKeyProperties(InternalEntityEntry dependentEntry, InternalEntityEntry principalEntry, IForeignKey foreignKey, Boolean setModified, Boolean fromQuery)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.FixupToPrincipal(InternalEntityEntry dependentEntry, InternalEntityEntry principalEntry, IForeignKey foreignKey, Boolean setModified, Boolean fromQuery)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.DelayedFixup(InternalEntityEntry entry, INavigation navigation, InternalEntityEntry referencedEntry, Boolean fromQuery)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.InitialFixup(InternalEntityEntry entry, Boolean fromQuery)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.StateChanged(InternalEntityEntry entry, EntityState oldState, Boolean fromQuery)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.StateChanged(InternalEntityEntry entry, EntityState oldState, Boolean fromQuery)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.FireStateChanged(EntityState oldState)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges, Boolean modifyProperties, Nullable`1 forceStateWhenUnknownKey)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode`1 node)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1 node, Func`2 handleNode)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1 node, Func`2 handleNode)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph[TState](EntityEntryGraphNode`1 node, Func`2 handleNode)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState targetState, EntityState storeGeneratedWithKeySetTargetState, Boolean forceStateWhenUnknownKey)
at Microsoft.EntityFrameworkCore.DbContext.SetEntityState(InternalEntityEntry entry, EntityState entityState)
at Microsoft.EntityFrameworkCore.DbContext.SetEntityState[TEntity](TEntity entity, EntityState entityState)
at Microsoft.EntityFrameworkCore.DbContext.Add[TEntity](TEntity entity)
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.Add(TEntity entity)
at Repro.Program.Main(String[] args) in C:\Stuff\AllTogetherNow\ThreeOne\ThreeOneApp.cs:line 23
Putting this on the backlog to check the first time we create a property accessor. This won't help in all cases because the property can be assigned a new instance of a different type at any time, and we don't want to do an additional check every time we access the property.
Hi, I have exactly the same problem on the latest version.
Include provider and version information
EF Core version: 5.0.10 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: .Net Core 5.0 Operating system: Windows 10 IDE: Visual Studio 2019 16.11.3
Here is the log:
System.NotSupportedException: Collection was of a fixed size. at System.SZArrayHelper.Add[T](T value) at Microsoft.EntityFrameworkCore.Metadata.Internal.ClrICollectionAccessor`3.Add(Object entity, Object value, Boolean forMaterialization) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.AddToCollection(InternalEntityEntry entry, INavigationBase navigation, InternalEntityEntry value, Boolean fromQuery) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.ToDependentFixup(InternalEntityEntry dependentEntry, InternalEntityEntry principalEntry, IForeignKey foreignKey, Boolean fromQuery) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.InitialFixup(InternalEntityEntry entry, Boolean fromQuery) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.StateChanged(InternalEntityEntry entry, EntityState oldState, Boolean fromQuery) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.StateChanged(InternalEntityEntry entry, EntityState oldState, Boolean fromQuery) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.FireStateChanged(EntityState oldState) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges, Boolean modifyProperties) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityStateAsync(EntityState entityState, Boolean acceptChanges, Boolean modifyProperties, Nullable`1 forceStateWhenUnknownKey, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintActionAsync(EntityEntryGraphNode`1 node, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraphAsync[TState](EntityEntryGraphNode`1 node, Func`3 handleNode, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.AddRangeAsync(IEnumerable`1 entities, CancellationToken cancellationToken) at WatchMyGame.Web.Dal.Services.ImportDataService.UpdateProjectsAsync(User user, String projectData, Boolean isManager, IDictionary`2 projects, CancellationToken cancellationToken) in C:\Lavoro\Git\WatchMyGame\Src\WatchMyGame.Web.Dal\Services\ImportDataService.cs:line 238 at WatchMyGame.Web.Dal.Services.ImportDataService.UpdateUserAsync(Int64 seasonId, User user, UserSeason userSeason, ImportAnagraficaItemModel anagrafica, IDictionary`2 projects, UserImportConfirmRequest config, CancellationToken cancellationToken) in C:\Lavoro\Git\WatchMyGame\Src\WatchMyGame.Web.Dal\Services\ImportDataService.cs:line 306 at WatchMyGame.Web.Dal.Services.ImportDataService.ProcessUserAsync(Int64 seasonId, User user, UserSeason userSeason, ImportAnagraficaItemModel anagrafica, IDictionary`2 projects, UserImportConfirmRequest config, CancellationToken cancellationToken) in C:\Lavoro\Git\WatchMyGame\Src\WatchMyGame.Web.Dal\Services\ImportDataService.cs:line 352 at WatchMyGame.Web.Dal.Services.ImportDataService.ConfirmImportAnagraficaAsync(Int64 userId, Int64 seasonId, UserImportConfirmRequest config, CancellationToken cancellationToken) in C:\Lavoro\Git\WatchMyGame\Src\WatchMyGame.Web.Dal\Services\ImportDataService.cs:line 94 at WatchMyGame.Web.Services.ImportService.ConfirmImportAnagraficaAsync(Int64 userId, Int64 seasonId, UserImportConfirmRequest request, CancellationToken cancellationToken) in C:\Lavoro\Git\WatchMyGame\Src\WatchMyGame.Web.Services\Services\ImportService.cs:line 117 at WatchMyGame.Web.Controllers.Api.ImportController.ConfirmAnagraficaAsync(UserImportConfirmRequest request, CancellationToken cancellationToken) in C:\Lavoro\Git\WatchMyGame\Src\WatchMyGame.Web\Controllers\Api\ImportController.cs:line 86 at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker) at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
@FrankIceBass Fixed-size collections, such as arrays, are not supported since EF needs to add elements to them.
@ajcvickers I hardly understand which is the fixed-size collections. I'm adding items to a DbSet with AddRangeAsync. I'm using just this on DbSet:
await this.context.ProjectUsers.AddRangeAsync(list, cancellationToken);
@FrankIceBass Typically a collection of one entity type on another entity type. For example, the collection of posts on a blog. This is known as a navigation. See Relationships in the docs.
@ajcvickers I really hardly understand. I'm using scaffolded db context and it is just a 1-N table. I will try to check more why this "feature" is annoying me so much. By the way I have the same exception even if i try to update objects into that DbSet.
Anyway.. thank you for your support.
@FrankIceBass Feel free to open a new issue attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate.
@FrankIceBass I'd guess that you are using sth like Array to initialize the navigation property from 1 to N for your relation somewhere during the entity instance initialization.
See the repro I attached initially, it might shed some light.
@v-zubritsky unfortunately it's not my case.
I have the same exception even trying to add items not related to parent entities.
var list = projectList.Where(item => !userProjects.Where(y => y.ProjectId == item.Id).Any()) .Select(x => new Ef.ProjectUser { CreationDate = DateTime.UtcNow, Deleted = false, IsManager = isManager, LastUpdate = DateTime.UtcNow, ProjectId = x.Id, UserId = user.Id }).ToList();
await this.context.ProjectUsers.AddRangeAsync(list, cancellationToken);
Hi everyone, I just solved it... well... it's strange solution but it worked for me. I was watching this.context.ChangeTracker.Entries()
and it was full of unchanged properties.
I just added this.context.ChangeTracker.Clear()
before running the code I posted above... well... it worked...
Calling .ToList()
solved the problem for me.
I was getting the above error message ( Collection was of a fixed size. at System.SZArrayHelper.Remove...
) ,
when I was setting
model.Foos = newFoos;
only when model.Foos
count was 1 and newFoos
was more than 1 or the other way around.
I feel the need to weigh in here, having encountered this error and scratched my head for over an hour as to where the fixed array was, why it updated and why it was failing to 'Remove' with an 'Add'.
Firstly, the exception misled me because I was performing a .Add(entity1)
followed by a .Remove(entity2)
. The exception was being thrown on the add.
Secondly, the fixed array was not in either entity1
or entity2
. My schema looked like the following:
[Table]
public class A
{
[Key]
public int AId { get; set; }
public IList<B>? Bs { get; set; } = new List<B>();
}
[Table]
public class B
{
public int AId { get; set; }
public int CId { get; set; }
[ForeignKey("AId")]
public IList<A> A { get; set; }
[ForeignKey("CId")]
public IList<C> C { get; set; }
}
[Table]
public class C
{
[Key]
public int CId { get; set; }
//I'd set as an array to avoid updating from here.
public IEnumerable<B> Bs { get; set; } = Array.Empty<B>();
}
Then when trying to add an A
, with a bunch of B
s in the list, I believe in the background it wanted to update the Array
of C
s through the change tracking.
In brief:
MyDbContext db = new(options);
//Perhaps I loaded some Cs earlier on in the same DbContext, bringing them into the local change tracking, perhaps why clearing the change tracking has worked for others
var bunchOfCs = db.Cs.ToList();
A myA = new();
myA.Bs.Add(new B() { AId = 123, BId = 234 });
db.As.Add(myA); //throws error
Changing the C.Bs
to a List
allowed it to run.
In conclusion, it might be a good idea to add a warning of this type of background behaviour along with the exception.
@FrankIceBass Fixed-size collections, such as arrays, are not supported since EF needs to add elements to them.
How is it not possible to take a fixed sized array and convert it into an array that is growable and not fixed?
How is it not possible to take a fixed sized array and convert it into an array that is growable and not fixed?
Arrays in C#/.NET are always fixed size. List<T>
, for example, can grow as required.
Description
Error message is not that descriptive as it could be for a case when fixed size collection (Array) is used for a navigation property. It'd be nice to be pointed to the problematic navigation property or entity type at least with a clean problem description in the error message.
Creating issue because of the conversation happening here https://github.com/dotnet/efcore/issues/6589#issuecomment-689041161
Code
I reproduced the issue on a sample used for another issue in this repo previously, so it's not that minimal (and won't probably work even, when this fixed collection case is improved, due to another configuration error), but should be okay for the error discussed. Repro.zip
Include provider and version information
EF Core version: 3.1.12 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: net48 Operating system: Windows 10 IDE: Visual Studio 2019 16.3