我真的不明白这个创建种子数据的方法
EnsurePopulated
发生了什么。
public static class SeedData
{
public static void EnsurePopulated(IApplicationBuilder app)
{
StoreDbContext context = app.ApplicationServices
.CreateScope().ServiceProvider.GetRequiredService<StoreDbContext>();
if (context.Database.GetPendingMigrations().Any())
{
context.Database.Migrate();
}
if (!context.Products.Any())
{
//here we add the products (I left just one in the code sample)
context.Products.AddRange(
new Product
{
Name = "Kayak",
Description = "A boat for one person",
Category = "Watersports",
Price = 275
});
context.SaveChanges();
}
}
}
这是我的 ASP.NET 应用程序的
Program.cs
文件。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<StoreDbContext>(opts =>
{
opts.UseSqlServer(builder.Configuration["ConnectionStrings:StortsStoreConnection"]);
});
builder.Services.AddScoped<IStoreRepository, EFStoreRepository>();
var app = builder.Build();
app.MapDefaultControllerRoute();
SeedData.EnsurePopulated(app);
app.Run();
IApplicationBuilder 参数的想法是什么?我们到底如何获取数据库上下文?我们用
.ApplicationServices
、.CreateScope()
、.ServiceProvider
、.GetRequiredService<StoreDbContext>()
做什么?您能解释一下其中每一项的作用吗?我不明白为什么我们不能将数据库上下文注入到类的构造函数中(如果它不是静态的)。您能为我澄清一下以这种方式播种数据的整个想法吗?我尝试查看调试器发生了什么,但没有太大帮助。请不要粗鲁,因为我对这个框架相当陌生。谢谢!
我们在IServiceCollection中注册服务,IServiceCollection接口用于构建依赖注入容器。例如,数据库上下文在 Program.cs 文件中的 Dependency Injection 容器中注册:
builder.Services.AddDbContext<StoreDbContext>(opts =>
{
opts.UseSqlServer(builder.Configuration["ConnectionStrings:StortsStoreConnection"]);
});
完全构建后,它会组成一个 IServiceProvider 实例,您可以使用它来解析服务。请阅读在应用程序启动时解决服务以了解更多信息。
您可以将 IServiceProvider 注入到任何类中。 IApplicationBuilder 类也可以通过 ApplicationServices 提供服务提供者。
默认情况下,实体框架上下文使用作用域生命周期添加到服务容器中,因为 Web 应用程序数据库操作通常作用于客户端请求。使用 .CreateScope() 创建一个新的 IServiceScope,可用于解析作用域服务。
ServiceProvider 类实现了 IServiceProvider ,使用
.GetRequiredService<StoreDbContext>()
方法从 IServiceProvider 获取 StoreDbContext 类型的服务。
StoreDbContext 上下文 = app.ApplicationServices .CreateScope().ServiceProvider.GetRequiredService();
这是为了解析 StoreDbContext,然后使用
context.Products.AddRange
和 context.SaveChanges();
来播种数据。您可以阅读为数据库添加种子以了解更多信息。