简体   繁体   English

Entity Framework Core 6 - 当 IDENTITY_INSERT 设置为 OFF 时,无法在表“角色”中插入标识列的显式值

[英]Entity Framework Core 6 - Cannot insert explicit value for identity column in table 'Roles' when IDENTITY_INSERT is set to OFF

I currently have a problem with EF6 and Fluent API.我目前在使用 EF6 和 Fluent API 时遇到问题。 When inserting into database where model have one to many relationship, I'm getting this error.当插入模型具有一对多关系的数据库时,出现此错误。 I've checked some related topics, but I want to keep autoincrement.我检查了一些相关主题,但我想保持自动增量。 Model without one to many relationship works perfectly.没有一对多关系的模型可以完美运行。

Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
 ---> Microsoft.Data.SqlClient.SqlException (0x80131904): Cannot insert explicit value for identity column in table 'Roles' when IDENTITY_INSERT is set to OFF.
   at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__188_0(Task`1 result)
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
ClientConnectionId:501a6880-e298-43d5-be69-fcbebacdb15e
Error Number:544,State:1,Class:16
   --- End of inner exception stack trace ---
   at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at WorkIT_Backend.Services.UserService.Create(String username, String password, String role) in C:\Users\Ondřej\Desktop\škola\2022 PRF\WS\OPR3\WorkIT_Backend\WorkIT_Backend\WorkIT_Backend\Services\UserService.cs:line 54
   at WorkIT_Backend.Controllers.UsersController.CreateUser(UserDto user) in C:\Users\Ondřej\Desktop\škola\2022 PRF\WS\OPR3\WorkIT_Backend\WorkIT_Backend\WorkIT_Backend\Controllers\UsersController.cs:line 57
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(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.<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__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Model classes模型类

public sealed class Role
{
    public long RoleId { get; set; }

    public string? Name { get; set; }

    public ICollection<User> Users { get; set; }

    public Role()
    {
        Users = new HashSet<User>();
    }
}
public class User
{
    public long UserId { get; set; }

    public string? UserName { get; set; }

    public string? PasswordHash { get; set; }
    public long RoleId { get; set; }

    public virtual Role Role { get; set; }

    public User()
    {
    }
}

OnModelCreating in dbcontext数据库上下文中的 OnModelCreating

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Role>(entity =>
        {
            entity.HasKey(q => q.RoleId);
            entity.Property(q => q.RoleId)
                .ValueGeneratedOnAdd();

            entity.Property(q => q.Name)
                .IsRequired();
            entity.HasIndex(q => q.Name)
                .IsUnique();
        });

        modelBuilder.Entity<User>(entity =>
        {
            entity.HasKey(q => q.UserId);
            entity.Property(q => q.UserId)
                .ValueGeneratedOnAdd();

            entity.Property(q => q.UserName)
                .IsRequired();

            entity.Property(q => q.PasswordHash)
                .IsRequired();

            entity.HasOne(u => u.Role)
                .WithMany(r => r.Users)
                .HasForeignKey(u => u.RoleId)
                .OnDelete(DeleteBehavior.ClientSetNull);
        });
    }

Method in service which is adding the user服务中添加用户的方法

public async Task<User> Create(string username, string password, string role)
    {
        EnsureNotNull(username, nameof(username));
        EnsureNotNull(password, nameof(password));
        EnsureNotNull(role, nameof(role));

        username = username.ToLower();

        if (_context.Users.Any(q => q.UserName == username))
            throw CreateException($"User {username} already exists.", null);

        var hash = _securityService.HashPassword(password);
        var userRole = await _roleService.GetRole(role);

        var ret = new User {UserName = username, PasswordHash = hash, Role = userRole};

        _context.Users.Add(ret);
        await _context.SaveChangesAsync();

        return ret;
    }

This method for adding roles works perfectly这种添加角色的方法非常有效


public class RoleService
{
    private readonly WorkItDbContext _context;
    private readonly SecurityService _securityService;


    public RoleService(WorkItDbContext context, SecurityService securityService)
    {
        _context = context;
        _securityService = securityService;
    }

    public async Task<Role> Create(string name)
    {
        EnsureNotNull(name, nameof(name));

        name = name.ToLower();
        if (_context.Roles.Any(q => q.Name == name))
            throw CreateException($"Role {name} already exists.", null);

        var ret = new Role {Name = name};
        _context.Add(ret);
        await _context.SaveChangesAsync();
        return ret;
    }

    public async Task<List<Role>> GetRoles()
    {
        var roles = await _context.Roles.ToListAsync();
        return roles;
    }

    public async Task<Role> GetRole(string name)
    {
        var role = await _context.Roles.FirstAsync(q => q.Name == name) ??
                   throw CreateException($"Role {name} does not exist.");
        return role;
    }
}

Program.cs程序.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton<IConfiguration>(builder.Configuration);
SecurityService securityService = new(builder.Configuration);
builder.Services.AddTransient<WorkItDbContext>();
builder.Services.AddSingleton<SecurityService>();
builder.Services.AddTransient<UserService>();
builder.Services.AddTransient<RoleService>();

I've different combination of dbcontext methods.我有不同的 dbcontext 方法组合。 I tried auto increment through anotation - identity.我尝试通过注释自动递增 - 身份。 I've checked SQL server and autoincrement is alright.我已经检查过 SQL Server 并且自动增量没问题。

Change改变

builder.Services.AddTransient<WorkItDbContext>();

to

builder.Services.AddDbContext<WorkItDbContext>();

and then your UserService and RoleService will share a WorkItDbContext, because it will be added as a Scoped service.然后您的 UserService 和 RoleService 将共享一个 WorkItDbContext,因为它将作为 Scoped 服务添加。 See DbContext in dependency injection for ASP.NET Core请参阅ASP.NET Core 的依赖注入中的 DbContext

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当 IDENTITY_INSERT 设置为 OFF 时,无法为标识列插入显式值。 (实体框架核心) - Cannot insert explicit value for identity column when IDENTITY_INSERT is set to OFF. (Entity Framework Core) 实体框架:当IDENTITY_INSERT设置为OFF时,无法为表&#39;[table]&#39;中的标识列插入显式值 - Entity Framework: Cannot insert explicit value for identity column in table '[table]' when IDENTITY_INSERT is set to OFF 实体框架核心:当IDENTITY_INSERT设置为OFF时,无法为表&#39;Relation&#39;中的Identity列插入显式值 - Entity framework core: Cannot insert explicit value for identity column in table 'Relation' when IDENTITY_INSERT is set to OFF 当IDENTITY_INSERT设置为OFF时,无法在TABLE中为Identity列插入显式值; .NET Core 2.1 - Cannot insert explicit value for identity column in TABLE when IDENTITY_INSERT is set to OFF; .NET Core 2.1 使用现有数据库和实体框架的代码优先:当IDENTITY_INSERT设置为OFF时,无法为表中的标识列插入显式值 - Code First With Existing Database, Entity Framework: Cannot insert explicit value for identity column in table when IDENTITY_INSERT is set to OFF 实体框架抛出无法为表中的“身份”列插入显式值…IDENTITY_INSERT设置为OFF时错误 - Entity Framework Throwing Cannot Insert Explicit Value for Identity Column In Table … When IDENTITY_INSERT is set to OFF Error SqlException:当 IDENTITY_INSERT 设置为 OFF 时,无法为表 [表名] 中的标识列插入显式值 - SqlException: Cannot insert explicit value for identity column in table [Table name] when IDENTITY_INSERT is set to OFF 出现错误:当IDENTITY_INSERT设置为OFF时,无法在表&#39;Table&#39;中为标识列插入显式值 - Getting Error: Cannot insert explicit value for identity column in table 'Table' when IDENTITY_INSERT is set to OFF 当IDENTITY_INSERT设置为OFF时,无法为表&#39;ActivityInstances中的标识列插入显式值 - Cannot insert explicit value for identity column in table 'ActivityInstances' when IDENTITY_INSERT is set to OFF SqlException:当IDENTITY_INSERT设置为OFF时,无法为表&#39;Recipe&#39;中的Identity列插入显式值 - SqlException: Cannot insert explicit value for identity column in table 'Recipe' when IDENTITY_INSERT is set to OFF
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM