在启用 Identity/Auth 的 EF Core 中播种数据时出现问题 .Net 5
Problem Seeding Data in EF Core with Identity/Auth Enabled .Net 5
我已经使用 .net 5 和 React 模板创建了一个 ASP.NET 核心 Web 应用程序,并在 VS 向导中启用了身份验证。为 dbContext 创建的代码是这样的:
public class ApplicationDbContext : ApiAuthorizationDbContext<ApplicationUser>
{
public ApplicationDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
{
}
我想在我从 Program.cs 调用的 seedData 方法中访问此 dbContext,如下所示:
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try { SeedData.Initialize(services); } ...
当我尝试在 SeedData / Initialize 中获取对我的 Context 的引用时,我得到一个空引用错误,因为在如下实例化 DbContextOptions 时缺少构造函数的第二个参数(null 显然是错误的,但我不不知道我应该传递什么)
public static class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using ApplicationDbContext context = new ApplicationDbContext(
serviceProvider.GetRequiredService<
DbContextOptions<ApplicationDbContext>>(),null);
试试这个:
首先,您必须创建范围并从 program.cs 中获取需要的服务
(ApplicationUser 继承自 IdentityUser )。
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
ApplicationDbContextSeed.SeedDefaultUserAsync(userManager)
.GetAwaiter().GetResult(;
}
host.Run();
}
接下来您必须在播种中创建静态播种方法 class 例如:
public class ApplicationDbContextSeed
{
public static async Task SeedDefaultUserAsync(UserManager<ApplicationUser> userManager)
{
var user = new ApplicationUser()
{
Email = "email",
UserName = "username",
};
await userManager.CreateAsync(user, "password");
}
}
您也可以在此 class
中播种您的数据库
public static async Task SeedSampleDataAsync(ApplicationDbContext context)
{
// Seed, if necessary
if (!context.TodoLists.Any())
{
context.TodoLists.Add(new TodoList
{
Title = "Shopping",
Items =
{
new TodoItem { Title = "Apples", Done = true },
new TodoItem { Title = "Milk", Done = true },
new TodoItem { Title = "Bread", Done = true },
new TodoItem { Title = "Toilet paper" },
new TodoItem { Title = "Pasta" },
new TodoItem { Title = "Tissues" },
new TodoItem { Title = "Tuna" },
new TodoItem { Title = "Water" }
}
});
await context.SaveChangesAsync();
}
}
最后在program.cs
中调用这个方法
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
ApplicationDbContextSeed.SeedDefaultUserAsync(userManager)
.GetAwaiter().GetResult(;
var context = services.GetRequiredService<ApplicationDbContext>();
await ApplicationDbContextSeed.SeedSampleDataAsync(context);
}
host.Run();
}
我已经使用 .net 5 和 React 模板创建了一个 ASP.NET 核心 Web 应用程序,并在 VS 向导中启用了身份验证。为 dbContext 创建的代码是这样的:
public class ApplicationDbContext : ApiAuthorizationDbContext<ApplicationUser>
{
public ApplicationDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
{
}
我想在我从 Program.cs 调用的 seedData 方法中访问此 dbContext,如下所示:
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try { SeedData.Initialize(services); } ...
当我尝试在 SeedData / Initialize 中获取对我的 Context 的引用时,我得到一个空引用错误,因为在如下实例化 DbContextOptions 时缺少构造函数的第二个参数(null 显然是错误的,但我不不知道我应该传递什么)
public static class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using ApplicationDbContext context = new ApplicationDbContext(
serviceProvider.GetRequiredService<
DbContextOptions<ApplicationDbContext>>(),null);
试试这个:
首先,您必须创建范围并从 program.cs 中获取需要的服务 (ApplicationUser 继承自 IdentityUser )。
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
ApplicationDbContextSeed.SeedDefaultUserAsync(userManager)
.GetAwaiter().GetResult(;
}
host.Run();
}
接下来您必须在播种中创建静态播种方法 class 例如:
public class ApplicationDbContextSeed
{
public static async Task SeedDefaultUserAsync(UserManager<ApplicationUser> userManager)
{
var user = new ApplicationUser()
{
Email = "email",
UserName = "username",
};
await userManager.CreateAsync(user, "password");
}
}
您也可以在此 class
中播种您的数据库public static async Task SeedSampleDataAsync(ApplicationDbContext context)
{
// Seed, if necessary
if (!context.TodoLists.Any())
{
context.TodoLists.Add(new TodoList
{
Title = "Shopping",
Items =
{
new TodoItem { Title = "Apples", Done = true },
new TodoItem { Title = "Milk", Done = true },
new TodoItem { Title = "Bread", Done = true },
new TodoItem { Title = "Toilet paper" },
new TodoItem { Title = "Pasta" },
new TodoItem { Title = "Tissues" },
new TodoItem { Title = "Tuna" },
new TodoItem { Title = "Water" }
}
});
await context.SaveChangesAsync();
}
}
最后在program.cs
中调用这个方法 public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
ApplicationDbContextSeed.SeedDefaultUserAsync(userManager)
.GetAwaiter().GetResult(;
var context = services.GetRequiredService<ApplicationDbContext>();
await ApplicationDbContextSeed.SeedSampleDataAsync(context);
}
host.Run();
}