public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add DbContext to the injection container
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(
this.Configuration.GetConnectionString("DefaultConnection")));
}
}
但是,IServiceCollection不充当服务提供者,并且由于DbContext没有在当前作用域(Startup.ConfigureServices)* 之前 * 注册到注入容器,因此我们无法通过依赖注入访问上下文。 Henk Mollema讨论了在启动here期间手动解析服务,但提到... 手动解析服务(又名服务定位器)是generally considered an anti-pattern ... [并且]您应该尽可能避免它。 Henk还提到,Startup构造函数的依赖注入非常有限,不包括Startup.ConfigureServices()中配置的服务,因此通过应用程序其余部分使用的注入容器,DbContext的使用是最简单和最合适的。 运行时的宿主服务提供程序可以将某些服务注入到Startup类的构造函数中,例如IConfiguration、IWebHostEnvironment(3.0之前的版本中为IHostingEnvironment)、ILoggerFactory和IServiceProvider。请注意,后者是由宿主层构建的示例,仅包含启动应用程序所必需的服务。 为了调用Database.EnsureCreated()或Database.Migrate(),我们可以并且希望在Startup.Configure()中自动解析DbContext,其中我们配置的服务现在通过DI可用:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add DbContext to the injection container
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(
this.Configuration.GetConnectionString("DefaultConnection")));
}
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, MyDbContext context)
{
if (env.IsDevelopment())
{
context.Database.EnsureCreated();
//context.Database.Migrate();
}
}
}
public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables();
if (env.IsDevelopment())
{
// This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
builder.AddApplicationInsightsSettings(developerMode: true);
}
Configuration = builder.Build();
Globals.Configuration = Configuration;
Globals.HostingEnvironment = env;
Globals.EnsureDatabaseCreated();
}
定义Globals.EnsureDatabaseCreated()如下:
public static void EnsureDatabaseCreated()
{
var optionsBuilder = new DbContextOptionsBuilder();
if (HostingEnvironment.IsDevelopment()) optionsBuilder.UseSqlServer(Configuration["Data:dev:DataContext"]);
else if (HostingEnvironment.IsStaging()) optionsBuilder.UseSqlServer(Configuration["Data:staging:DataContext"]);
else if (HostingEnvironment.IsProduction()) optionsBuilder.UseSqlServer(Configuration["Data:live:DataContext"]);
var context = new ApplicationContext(optionsBuilder.Options);
context.Database.EnsureCreated();
optionsBuilder = new DbContextOptionsBuilder();
if (HostingEnvironment.IsDevelopment()) optionsBuilder.UseSqlServer(Configuration["Data:dev:TransientContext"]);
else if (HostingEnvironment.IsStaging()) optionsBuilder.UseSqlServer(Configuration["Data:staging:TransientContext"]);
else if (HostingEnvironment.IsProduction()) optionsBuilder.UseSqlServer(Configuration["Data:live:TransientContext"]);
new TransientContext(optionsBuilder.Options).Database.EnsureCreated();
}
我正在开发ASP.NET核心6 Web API。 在Program.cs中构建应用程序后,我编写了下面的代码。
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
using var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
context.Database.EnsureCreated();
}
8条答案
按热度按时间14ifxucb1#
我认为这是一个重要的问题,应该好好回答!
context.Database.EnsureCreated()
是新的EF核心方法,可确保上下文的数据库存在。如果存在,则不执行任何操作。如果不存在,则创建数据库及其所有方案,并确保它与此上下文的模型兼容。DbContext.Database.Migrate()
方法来确保创建数据库并应用所有迁移。context.Database.EnsureCreated()
等同于下列EF 6方法:1.程序包管理器控制台:
1.来源代码:
或
将上下文的任何挂起迁移应用于数据库。如果数据库不存在,将创建该数据库。
context.Database.Migrate()
等同于下列EF 6方法:1.程序包管理器控制台:
1.使用自定义DbMigrationsConfiguration:
启用自动迁移=假;或使用DbMigrator。
如果你使用的是migrations,则有
context.Database.Migrate()
;如果你不需要migrations,而只需要一个快速的数据库(通常用于测试),则使用context.Database.EnsureCreated()/EnsureDeleted()。ars1skjm2#
根据James P和Bassam Alugili提供的信息,我最后做的是将以下代码行添加到
Startup
类(Startup.cs)中的Configure
方法:3lxsmp7m3#
通常,
DbContext
将被添加到Startup.ConfigureServices()
中的依赖注入容器,如下所示:但是,
IServiceCollection
不充当服务提供者,并且由于DbContext
没有在当前作用域(Startup.ConfigureServices
)* 之前 * 注册到注入容器,因此我们无法通过依赖注入访问上下文。Henk Mollema讨论了在启动here期间手动解析服务,但提到...
手动解析服务(又名服务定位器)是generally considered an anti-pattern ... [并且]您应该尽可能避免它。
Henk还提到,
Startup
构造函数的依赖注入非常有限,不包括Startup.ConfigureServices()
中配置的服务,因此通过应用程序其余部分使用的注入容器,DbContext的使用是最简单和最合适的。运行时的宿主服务提供程序可以将某些服务注入到
Startup
类的构造函数中,例如IConfiguration
、IWebHostEnvironment
(3.0之前的版本中为IHostingEnvironment
)、ILoggerFactory
和IServiceProvider
。请注意,后者是由宿主层构建的示例,仅包含启动应用程序所必需的服务。为了调用
Database.EnsureCreated()
或Database.Migrate()
,我们可以并且希望在Startup.Configure()
中自动解析DbContext,其中我们配置的服务现在通过DI可用:请记住,作为EF Core文档中引用的Bassam Alugili's answer,
Database.EnsureCreated()
和Database.Migrate()
不应一起使用,因为其中一个确保现有迁移应用于数据库(如果需要,将创建该数据库)。另一个仅确保数据库存在,如果不存在,则创建一个反映您的DbContext
的数据库。包括通过上下文中的API完成的任何播种。bsxbgnwa4#
作为一个前瞻,你应该阅读罗文米勒的this:
...
EnsureCreated
完全绕过迁移,只为您创建架构,您不能将其与迁移混合使用。EnsureCreated
专为测试或快速原型设计,您可以在每次删除并重新创建数据库时使用。如果您正在使用迁移,并希望在应用启动时自动应用它们,则可以改用context.Database.Migrate()
。根据答案here,您需要将
Globals.EnsureDatabaseCreated();
添加到Startup.cs
:Startup.cs中的启动功能:
定义
Globals.EnsureDatabaseCreated()
如下:要使用
context.Database.Migrate()
,请参见here或here。icnyk63a5#
bxfogqkk6#
此外,如果在上下文的构造函数中调用它,可能会影响性能......在将
EnsureCreated
移到setup.cs实用程序之后,我注意到响应时间有了相当大的改进。注意:我使用的是EFC和UWP。
42fyovps7#
如果您正在使用VS 2022/. Net Version 6,并且正在尝试找到创建数据库的方法,那么
执行以下步骤
从包管理器控制台通过包管理器添加Microsoft. EntityFramework. Tools引用
运行步骤1
InitialMigration这里是自定义名称,您可以键入任何您想要的..让它运行
第二步
这将创建您的数据库。
mec1mxoz8#
我正在开发ASP.NET核心6 Web API。
在
Program.cs
中构建应用程序后,我编写了下面的代码。context.Database.EnsureCreated()
确保上下文的数据库存在。希望我帮上忙了。