当我有两个 DbContext a) IdentityDbContext & b) AppDbContext 时如何播种用户、角色
How to seed users, roles when I have TWO DbContext, a) IdentityDbContext & b) AppDbContext
通常我会将播种用户的代码放在 OnModelCreating()
one
DbContext 中不是问题。
最近建议将identity's DbContext
与App's DbContext
分开,这增加了两个 DbContext 和一些混乱。
public UseManagementDbContext(DbContextOptions<UseManagementDbContext> options) : base(options)
// security/users 分离
public AppDbContext(DbContextOptions<MyDbContext> options) : base(options)
But when you have two separate DbContexts, How do I seed the user / role data?
IdentityDbContext
-- 这具有播种的所有 <IdentityUser>
上下文
AppDbContext
-- 这没有 <IdentityUser>
上下文,但我的迁移使用此上下文。
能否请您帮助如何播种用户和角色数据,并且是迁移或启动等的一部分
更新:使用核心6样本,@Zhi Lv - 我如何改造到program.cs my seedData when the app is fired up
我的 Program.cs
最初是从 ASP Core 3.1 模板创建的,它看起来像这样,我应该重构什么,(奇怪的是 link at MS, there are no class name brackets ,那么我的种子从哪里设置和调用?
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
要播种用户和角色数据,您可以创建静态 class,如下所示:
//required
//using Microsoft.AspNetCore.Identity;
//using Microsoft.EntityFrameworkCore;
public static class SeedRoles
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var context = new ApplicationDbContext(serviceProvider.GetRequiredService<DbContextOptions<ApplicationDbContext>>()))
{
string[] roles = new string[] { "Owner", "Administrator", "Tests2", "Editor", "Buyer", "Business", "Seller", "Subscriber" };
var newrolelist = new List<IdentityRole>();
foreach (string role in roles)
{
if (!context.Roles.Any(r => r.Name == role))
{
newrolelist.Add(new IdentityRole(role));
}
}
context.Roles.AddRange(newrolelist);
context.SaveChanges();
}
}
}
注意: 在我的应用程序中,我使用Asp.net 6,数据库上下文是ApplicationDbContext
,你可以将其更改为你的。
然后,在program.cs文件中,可以在var app = builder.Build();
行之后调用种子角色方法,代码如下:
// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>() //enable Identity Role
.AddEntityFrameworkStores<ApplicationDbContext>() ;
builder.Services.AddControllersWithViews();
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
SeedRoles.Initialize(services);
}
结果如下,运行申请后,会播种数据:
由于您使用了两个 DBcontext,您还可以创建多个静态方法来播种数据。
更多详细信息,您可以查看official document and sample。
更新:
要播种用户,可以使用UserManager在seed方法中创建用户,代码如下:
public static class SeedUsers
{
public static async Task InitializeAsync(IServiceProvider serviceProvider)
{
using (UserManager<IdentityUser> _userManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>())
{
var userlist = new List<SeedUserModel>()
{
new SeedUserModel(){ UserName="John@hotmail.com",Password= "Abc12345!" },
new SeedUserModel(){UserName ="David@hotmial.com", Password="Abc12345!"}
};
foreach (var user in userlist)
{
if (!_userManager.Users.Any(r => r.UserName == user.UserName))
{
var newuser = new IdentityUser { UserName = user.UserName, Email = user.UserName };
var result = await _userManager.CreateAsync(newuser, user.Password);
}
}
}
}
}
截图是这样的:
[注意] 从截图中我们可以看到,EmailConfirmed 列默认为False
。如果启用了Email Confirm操作,需要将值修改为True
,才能登录成功。
更新二:
对于以前的版本:例如Asp.net 5或Asp.net core 3.1,您可以在Program.cs中添加种子初始化器,代码如下:
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
SeedData.Initialize(services);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
}
host.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
通常我会将播种用户的代码放在 OnModelCreating()
one
DbContext 中不是问题。
最近建议将identity's DbContext
与App's DbContext
分开,这增加了两个 DbContext 和一些混乱。
public UseManagementDbContext(DbContextOptions<UseManagementDbContext> options) : base(options)
// security/users 分离public AppDbContext(DbContextOptions<MyDbContext> options) : base(options)
But when you have two separate DbContexts, How do I seed the user / role data?
IdentityDbContext
-- 这具有播种的所有<IdentityUser>
上下文AppDbContext
-- 这没有<IdentityUser>
上下文,但我的迁移使用此上下文。
能否请您帮助如何播种用户和角色数据,并且是迁移或启动等的一部分
更新:使用核心6样本,@Zhi Lv - 我如何改造到program.cs my seedData when the app is fired up
我的 Program.cs
最初是从 ASP Core 3.1 模板创建的,它看起来像这样,我应该重构什么,(奇怪的是 link at MS, there are no class name brackets ,那么我的种子从哪里设置和调用?
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
要播种用户和角色数据,您可以创建静态 class,如下所示:
//required
//using Microsoft.AspNetCore.Identity;
//using Microsoft.EntityFrameworkCore;
public static class SeedRoles
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var context = new ApplicationDbContext(serviceProvider.GetRequiredService<DbContextOptions<ApplicationDbContext>>()))
{
string[] roles = new string[] { "Owner", "Administrator", "Tests2", "Editor", "Buyer", "Business", "Seller", "Subscriber" };
var newrolelist = new List<IdentityRole>();
foreach (string role in roles)
{
if (!context.Roles.Any(r => r.Name == role))
{
newrolelist.Add(new IdentityRole(role));
}
}
context.Roles.AddRange(newrolelist);
context.SaveChanges();
}
}
}
注意: 在我的应用程序中,我使用Asp.net 6,数据库上下文是ApplicationDbContext
,你可以将其更改为你的。
然后,在program.cs文件中,可以在var app = builder.Build();
行之后调用种子角色方法,代码如下:
// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>() //enable Identity Role
.AddEntityFrameworkStores<ApplicationDbContext>() ;
builder.Services.AddControllersWithViews();
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
SeedRoles.Initialize(services);
}
结果如下,运行申请后,会播种数据:
由于您使用了两个 DBcontext,您还可以创建多个静态方法来播种数据。
更多详细信息,您可以查看official document and sample。
更新:
要播种用户,可以使用UserManager在seed方法中创建用户,代码如下:
public static class SeedUsers
{
public static async Task InitializeAsync(IServiceProvider serviceProvider)
{
using (UserManager<IdentityUser> _userManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>())
{
var userlist = new List<SeedUserModel>()
{
new SeedUserModel(){ UserName="John@hotmail.com",Password= "Abc12345!" },
new SeedUserModel(){UserName ="David@hotmial.com", Password="Abc12345!"}
};
foreach (var user in userlist)
{
if (!_userManager.Users.Any(r => r.UserName == user.UserName))
{
var newuser = new IdentityUser { UserName = user.UserName, Email = user.UserName };
var result = await _userManager.CreateAsync(newuser, user.Password);
}
}
}
}
}
截图是这样的:
[注意] 从截图中我们可以看到,EmailConfirmed 列默认为False
。如果启用了Email Confirm操作,需要将值修改为True
,才能登录成功。
更新二:
对于以前的版本:例如Asp.net 5或Asp.net core 3.1,您可以在Program.cs中添加种子初始化器,代码如下:
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
SeedData.Initialize(services);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred seeding the DB.");
}
}
host.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}