迁移时出错-数据库中已经有一个名为“ AspNetRoles”的对象。 (实体框架核心)

时间:2018-08-22 04:58:14

标签: c# asp.net-identity entity-framework-core

我正在尝试使用ASP.NET Identity Core添加自定义配置文件详细信息。我尝试如下扩展IdentityUser类:

public class ApplicationUser : IdentityUser
{
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
}

这是我的ApplicationDbContext,它继承了IdentityDbContext:

public class ApplicationIdentityDbContext : IdentityDbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=TokenDatabase;Trusted_Connection=True;");
    }
}

这是我的startup.cs文件:

public class Startup
{
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // ===== Add our DbContext ========
            services.AddDbContext<ApplicationIdentityDbContext>();

            // ===== Add Identity ========
            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationIdentityDbContext>()
                .AddDefaultTokenProviders();



            // ===== Add Jwt Authentication ========
            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // => remove default claims

            services
                .AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

                })
                .AddJwtBearer(cfg =>
                {
                    cfg.RequireHttpsMetadata = false;
                    cfg.SaveToken = true;
                    cfg.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidIssuer = Configuration["JwtIssuer"],
                        ValidAudience = Configuration["JwtIssuer"],
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"])),
                        ClockSkew = TimeSpan.Zero // remove delay of token when expire
                    };
                });

            services.AddSwaggerGen(x =>
            {
                x.SwaggerDoc("v1", new Info
                {
                    Title = "ASP NET .Identity Core Example"
                });

                var xmlFilePath = System.AppDomain.CurrentDomain.BaseDirectory + @"WebApiJwt.xml";
                x.IncludeXmlComments(xmlFilePath);
            });


            // ===== Add MVC ========
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(
            IApplicationBuilder app, 
            IHostingEnvironment env,
            ApplicationIdentityDbContext dbContext
        )
        {
            // ===== Create tables ======
            dbContext.Database.Migrate();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }


            app.UseSwagger();
            app.UseSwaggerUI(x =>
            {
                x.SwaggerEndpoint("/swagger/v1/swagger.json", "Core API");
            });

            // ===== Use Authentication ======
            app.UseAuthentication();
            app.UseMvc();         
        }
   }

我在执行此操作时遇到2个问题:

  1. 首先,当我尝试添加迁移时,出现错误An error occurred while calling method 'BuildWebHost' on class 'Program'. Continuing without the application service provider. Error: There is already an object named 'AspNetRoles' in the database.

enter image description here

  1. 我无法使用自定义个人资料信息更新AspNetUsers,我尝试添加:

        // ===== Add Identity ========
        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationIdentityDbContext>()
            .AddDefaultTokenProviders();
    

    类型为ApplicationUser的类型,但是AspNetUsers表不会更新这些多余的列。

2 个答案:

答案 0 :(得分:1)

简短地浏览,我注意到的第一件事是您应该使用Generic IdentityDbContext:

public class ApplicationIdentityDbContext : IdentityDbContext<ApplicationUser>

完全推荐的方案:

  1. 定义您的ApplicationUser类:

2.define上下文(我更喜欢这里不是硬编码连接字符串):

public class ApplicationIdentityDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationIdentityDbContext (DbContextOptions<ApplicationIdentityDbContext> options): base(options)
    {
    }
}
  1. 在appsettings.json中定义连接字符串:

“ ConnectionStrings”:{     “ DefaultConnection”:“这里是您的连接字符串”},

  1. 在ConfigureServices中,您应该添加:

        // ===== Add our DbContext ========
        services.AddDbContext<ApplicationIdentityDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    
        // ===== Add Identity ========
        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationIdentityDbContext>()
            .AddDefaultTokenProviders();
    
  2. 执行两个命令:

添加迁移NewMigrationName

更新数据库

  1. 为避免迁移错误,您可能会看到以下文章:

There is already an object named AspNetRoles in the database. (entity-framework-core)

There is already an object named 'AspNetRoles' in the database

https://github.com/aspnet/EntityFrameworkCore/issues/4649

答案 1 :(得分:0)

如果数据库已初始化,则在使用迁移时注释掉Database.EnsureCreated();