我真的不明白在这个创建种子数据的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参数的思想是什么?我们如何确切地获得db上下文?我们使用.ApplicationServices
、.CreateScope()
、.ServiceProvider
、.GetRequiredService<StoreDbContext>()
来做什么?你能解释一下每一个的作用吗?我不明白为什么我们不能直接将db上下文注入到类的构造函数中(如果它不是静态的)。你能为我澄清一下以这种方式播种数据的整个想法吗?我试着查看调试器发生了什么,但没有多大帮助。请不要粗鲁,因为我是相当新的框架。谢谢你,谢谢
1条答案
按热度按时间r6l8ljro1#
我们在IServiceCollection中注册服务,IServiceCollection接口用于构建依赖注入容器。例如,数据库上下文在Program.cs文件中注册到Dependency Injection容器:
字符串
在完全构建完成后,它被组合成一个IServiceProvider示例,您可以使用它来解析服务。阅读在应用程序启动时解决服务以了解更多信息。
您可以将IServiceProvider注入到任何类中。IApplicationBuilder类也可以通过ApplicationServices提供服务提供者。
默认情况下,实体框架上下文使用范围生命周期添加到服务容器,因为Web应用程序数据库操作的范围通常是客户端请求。使用.CreateScope()创建一个新的IServiceScope,可用于解析限定范围的服务。
ServiceProvider类实现了IServiceProvider,使用
.GetRequiredService<StoreDbContext>()
方法从IServiceProvider获取StoreDbContext类型的服务。System. out. println();
这是用于解析StoreDbContext,然后使用
context.Products.AddRange
和context.SaveChanges();
来播种数据。你可以阅读种子数据库了解更多。