EF Core 8执行批量插入时抛出NotSupportedException异常
EF Core 8 两次插入操作抛出
System.NotSupportedException 问题 问题场景
在EF Core 8的方法中执行两次插入操作时触发异常:先向Table1添加新记录并保存,接着通过SqlQuery从其他表查询数据,转换为关联Table1的Table3对象集合,调用AddRange插入时抛出异常:System.NotSupportedException: Specified method is not supported.
代码示例
_context.Table1.Add(table1obj); await _context.SaveChangesAsync(cancellationToken).ConfigureAwait(false); var path = await _context.Database.SqlQuery<Table2Dto>($$""" SELECT... """) .ToListAsync(cancellationToken: cancellationToken).ConfigureAwait(false); var table3obj = path.ConvertAll(x => new Table3 { Name = x.Name, OrderNumber = x.OrderNumber, Table1RefId = x.Id }); _context.Table3.AddRange(table3obj); await _context.SaveChangesAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
完整错误栈
System.NotSupportedException: Specified method is not supported. at System.Linq.ThrowHelper.ThrowNotSupportedException() at System.Linq.EmptyPartition`1.System.Collections.Generic.ICollection<TElement>.Add(TElement item) at Microsoft.EntityFrameworkCore.Metadata.Internal.ClrICollectionAccessor`3.AddStandalone(Object collection, Object value) at Microsoft.EntityFrameworkCore.Metadata.Internal.ClrICollectionAccessor`3.Add(Object entity, Object value, Boolean forMaterialization) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.AddToCollection(INavigationBase navigationBase, 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.SetReferenceOrAddToCollection(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, InternalEntityEntry duplicateEntry, 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, Nullable`1 fallbackState) 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.EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState targetState, EntityState storeGeneratedWithKeySetTargetState, Boolean forceStateWhenUnknownKey) at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.SetEntityState(InternalEntityEntry entry, EntityState entityState) at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.SetEntityStates(IEnumerable`1 entities, EntityState entityState) at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.AddRange(IEnumerable`1 entities) at WebSTapp.Server.Repositories.Activities.ActivityRepository.AddPathToActivity(ActivityAssignment asss, String activityId, String dataAreaId, Int32 assignmentId, CancellationToken cancellationToken) in D:\sources\WebST\WebST-v2\WebSTapp\Server\Repositories\Activities\ActivityRepository.cs:line 660 at WebSTapp.Server.Services.Activities.ActivityService.CreateActivitiesAssignment(ActivitiesAssignmentRequest activitiesAssignmentDto, CancellationToken cancellationToken) in D:\sources\WebST\WebST-v2\WebSTapp\Server\Services\Activities\ActivityService.cs:line 263 at WebSTapp.Server.Controllers.AssignmentsController.CreateAssignement(ActivitiesAssignmentRequest activitiesAssignmentDto) in D:\sources\WebST\WebST-v2\WebSTapp\Server\Controllers\AssignmentsController.cs:line 65 at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) 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|25_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|20_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.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker) at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Hellang.Middleware.ProblemDetails.ProblemDetailsMiddleware.Invoke(HttpContext context)
解决方案
从错误栈分析,问题出在EF Core维护导航属性时,尝试向只读集合添加元素导致的。以下是几种可行的解决方法:
修正导航属性类型:检查Table1中关联Table3的集合属性,确保不是只读类型。比如将
IReadOnlyCollection<Table3>改为可写的ICollection<Table3>:// 错误写法 public IReadOnlyCollection<Table3> Table3s { get; } = new List<Table3>(); // 正确写法 public ICollection<Table3> Table3s { get; set; } = new List<Table3>();手动设置实体状态:绕过EF Core的自动导航修复逻辑,直接将Table3对象的状态设为
Added:foreach (var item in table3obj) { _context.Entry(item).State = EntityState.Added; } await _context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);分离已跟踪的Table1实体:保存Table1后,将其从上下文跟踪中分离,避免EF Core尝试维护关联关系:
_context.Table1.Add(table1obj); await _context.SaveChangesAsync(cancellationToken).ConfigureAwait(false); _context.Entry(table1obj).State = EntityState.Detached;检查Dto的关联配置:确保Table2Dto没有定义与Table1或Table3相关的导航属性,防止EF Core错误跟踪无关关联。
内容的提问来源于stack exchange,提问作者mysiek44
相关产品推荐
相关产品推荐

