首页 > 解决方案 > 尝试在 .net 核心的代码中迁移表

问题描述

我正在使用Aspnet.Identity设置IdentityServer4。我遵循了一个教程,该教程展示了如何在代码中创建数据库和种子。我有一个看起来像这样的方法:

public static void SeedIdentityServerDatabase(this IApplicationBuilder app)
{
    using (var scope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
    {
        var serviceProvider = scope.ServiceProvider;
        var persistedGrantDbContext = serviceProvider.GetRequiredService<PersistedGrantDbContext>();
        var configurationDbContext = serviceProvider.GetRequiredService<ConfigurationDbContext>();

        persistedGrantDbContext.Database.Migrate();
        configurationDbContext.Database.Migrate();

        CreateIdentityResources(configurationDbContext);
        CreateApiResources(configurationDbContext);
        CreateClients(configurationDbContext);
    }
}

这可以毫无问题地创建我的数据库以及IdentityServer4所需的表/数据。

我现在正在阅读使用AspNet.Identity实现的IdentityServer文档,但它显示的是MVC而不是Api,我想继续按照以前的方式进行操作。

所以我将我的DbContext更新为此

public class DatabaseContext : IdentityDbContext<User>
{
    // ReSharper disable once SuggestBaseTypeForParameter
    public DatabaseContext(DbContextOptions<DatabaseContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);
    }
}

我的用户类对此:

public class User : IdentityUser
{
}

我的创业公司现在有这个:

services.Configure<Config>(Configuration.GetSection("ConnectionStrings"));

var buildServiceProvider = services.BuildServiceProvider();
var config = buildServiceProvider.GetService<IOptions<Config>>();

services.AddDbContext<DatabaseContext>(options => options.UseSqlServer(config.Value.ConnectionString));
services.AddIdentity<User, IdentityRole>().AddEntityFrameworkStores<DatabaseContext>()
    .AddDefaultTokenProviders();

我试图将我的种子方法更新为:

public static void SeedIdentityServerDatabase(this IApplicationBuilder app)
{
    using (var scope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
    {
        var serviceProvider = scope.ServiceProvider;
        var persistedGrantDbContext = serviceProvider.GetRequiredService<PersistedGrantDbContext>();
        var configurationDbContext = serviceProvider.GetRequiredService<ConfigurationDbContext>();
        var databaseContext = serviceProvider.GetRequiredService<DatabaseContext>();

        persistedGrantDbContext.Database.Migrate();
        configurationDbContext.Database.Migrate();
        databaseContext.Database.Migrate();

        CreateIdentityResources(configurationDbContext);
        CreateApiResources(configurationDbContext);
        CreateClients(configurationDbContext);
        CreateUsers(serviceProvider);
    }
}

private static void CreateUsers(IServiceProvider provider)
{
    const string email = "test.test@test.com";
    var userManager = provider.GetRequiredService<UserManager<User>>();
    var administrator = userManager.FindByEmailAsync(email).Result;

    if (administrator != null) return;

    administrator = new User {UserName = email, Email = email, EmailConfirmed = true};
    var result = userManager.CreateAsync(administrator, "password").Result;

    if (!result.Succeeded)
        throw new Exception(result.Errors.First().Description);

    result = userManager.AddClaimsAsync(administrator, new[]
    {
        new Claim(JwtClaimTypes.Name, "Test Test"),
        new Claim(JwtClaimTypes.GivenName, "Test"),
        new Claim(JwtClaimTypes.FamilyName, "Test"),
        new Claim(JwtClaimTypes.Email, email),
        new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean)
    }).Result;

    if (!result.Succeeded)
        throw new Exception(result.Errors.First().Description);
}

当它到达该CreateUsers方法时,它无法说明:

SqlException:对象名称“AspNetUsers”无效。

以下是它创建的表:

在此处输入图像描述

有谁知道我做错了什么?

标签: entity-frameworkasp.net-coreasp.net-identityidentityserver4

解决方案


很难说没有看到您的CreateUsers方法的代码,但默认情况下,许多UserManager/SignInManager方法似乎AspNetUsers默认查找表(除非您指定不同的表名)。要继续使用默认值,您可以将其添加到类的OnModelCreating方法中DatabaseContext

builder.Entity<User>(b => b.ToTable("AspNetUsers"));

否则,您的Migrate命令可能会创建一个UserManager/SignInManager不知道的“用户”表。如果您希望将该表称为“用户”,那很好,只需将上面的内容更改为:

builder.Entity<User>(b => b.ToTable("Users"));

这样,UserManager/SignInManager将知道要为User实体使用哪个表。

参考:ASP.NET Core 中的身份模型自定义


推荐阅读