相关文章推荐

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I have the following code that should seed my database. It get's called from the startup class in the Configure method, but throws an exception when calling: RoleManager.AddToRole(user, role); exception indicates a FK violation on UserId in ASP_NET_USERS. This is to be expected, because after checking the database I can see that it did create the new role, but not the new user. So naturally adding a new user->role relation to the database will violate a FK constraint. This is the code seeding the database:

        public async Task CreateUserAsync() {
            if (! await _userManager.Users.AnyAsync()) {
                var adminRole = new IdentityRole("admin");
                await _roleManager.CreateAsync(adminRole);
                var user = new IdentityUser {
                    Email = "[email protected]",
                    EmailConfirmed = true,
                    UserName = "superadmin"
                await _userManager.CreateAsync(user, "password");
                await _userManager.AddToRoleAsync(user, "admin");
Startup.cs:
        public void ConfigureServices(IServiceCollection services) {
            services.AddMvc();
            services.AddDbContext<DatabaseContext>(options =>
                options.UseNpgsql(
                    "Host = blablabla; Username = blabla; Password = blablabla; Database = db1"
            services.AddIdentity<IdentityUser, IdentityRole>()
                .AddEntityFrameworkStores<DatabaseContext>()
                .AddDefaultTokenProviders();
            services.AddTransient<IEmailSender, MessageServices>();
            services.AddTransient<ISmsSender, MessageServices>();
            services.AddTransient<DataSeeder>();
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public async void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, DataSeeder seeder) {
            loggerFactory.AddConsole(LogLevel.Debug);
            loggerFactory.AddDebug();
            app.UseMvc();
            app.UseStaticFiles();
            app.UseIdentity();
            await seeder.CreateUserAsync();
            // Add JWT generation endpoint:
            var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SecretKey));
            var options = new TokenProviderOptions {
                Audience = "ExampleAudience",
                Issuer = "ExampleIssuer",
                SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256),
            app.UseMiddleware<TokenProviderMiddleware>(Options.Create(options));

The exception:

Microsoft.EntityFrameworkCore.DbUpdateException was unhandled by user code
  HResult=-2146233088
  Message=An error occurred while updating the entries. See the inner exception for details.
  Source=Microsoft.EntityFrameworkCore.Relational
  StackTrace:
       at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.<ExecuteAsync>d__32.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.<ExecuteAsync>d__1.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<SaveChangesAsync>d__45.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<SaveChangesAsync>d__43.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at Microsoft.EntityFrameworkCore.DbContext.<SaveChangesAsync>d__30.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`4.<UpdateAsync>d__21.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at Microsoft.AspNetCore.Identity.UserManager`1.<UpdateUserAsync>d__159.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at Microsoft.AspNetCore.Identity.UserManager`1.<AddToRoleAsync>d__99.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
       at ShipviewWebsite.Infrastructure.DataSeeder.<CreateUserAsync>d__4.MoveNext() in D:\_Dev\ShipviewWebsite\src\ShipviewWebsite\Infrastructure\DataSeeder.cs:line 37
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
       at ShipviewWebsite.Startup.<Configure>d__6.MoveNext() in D:\_Dev\ShipviewWebsite\src\ShipviewWebsite\Startup.cs:line 59
  InnerException: 
       BaseMessage=insert or update on table "AspNetUserRoles" violates foreign key constraint "FK_AspNetUserRoles_AspNetUsers_UserId"
       Code=23503
       ConstraintName=FK_AspNetUserRoles_AspNetUsers_UserId
       Detail=Key (UserId)=(1cacc722-1ffb-46f4-b871-a7900fabb178) is not present in table "AspNetUsers".
       File=ri_triggers.c
       HResult=-2146233088
       InternalPosition=0
       Line=3302
       Message=23503: insert or update on table "AspNetUserRoles" violates foreign key constraint "FK_AspNetUserRoles_AspNetUsers_UserId"
       MessageText=insert or update on table "AspNetUserRoles" violates foreign key constraint "FK_AspNetUserRoles_AspNetUsers_UserId"
       Position=0
       Routine=ri_ReportViolation
       SchemaName=public
       Severity=ERROR
       Source=Npgsql
       SqlState=23503
       TableName=AspNetUserRoles
       StackTrace:
            at Npgsql.NpgsqlConnector.<DoReadMessageAsync>d__6.MoveNext()
         --- End of stack trace from previous location where exception was thrown ---
            at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
            at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
            at Npgsql.NpgsqlConnector.<ReadMessageWithPrependedAsync>d__5.MoveNext()
         --- End of stack trace from previous location where exception was thrown ---
            at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
            at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
            at Npgsql.NpgsqlDataReader.<NextResultInternalAsync>d__1.MoveNext()
         --- End of stack trace from previous location where exception was thrown ---
            at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
            at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
            at Npgsql.NpgsqlDataReader.<NextResultAsync>d__46.MoveNext()
         --- End of stack trace from previous location where exception was thrown ---
            at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
            at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
            at Npgsql.NpgsqlCommand.<ExecuteAsync>d__0.MoveNext()
         --- End of stack trace from previous location where exception was thrown ---
            at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
            at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
            at Npgsql.NpgsqlCommand.<ExecuteDbDataReaderInternalAsync>d__4.MoveNext()
         --- End of stack trace from previous location where exception was thrown ---
            at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
            at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
            at Npgsql.NpgsqlCommand.<ExecuteDbDataReaderAsync>d__98.MoveNext()
         --- End of stack trace from previous location where exception was thrown ---
            at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
            at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
            at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.<ExecuteAsync>d__20.MoveNext()
         --- End of stack trace from previous location where exception was thrown ---
            at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
            at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
            at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.<ExecuteAsync>d__32.MoveNext()
       InnerException: 
          

There is likely to be an error in the creation of the user which should be visible in the logging output. If you stick a breakpoint just before the CreateAsync and clear your log then run over it you should see the issue. Also see this: http://stackoverflow.com/questions/41280345/asp-net-core-identity-the-insert-statement-conflicted-with-the-foreign-key-cons

Thanks for the link, it did indeed turn out that there was an error in the user creation, but it had to do with an override of the users primary key and with the identity framework not respecting that key constraint. The error messages didn't explain it but debugging it showed how the id's were different.

 
推荐文章