asp.net 如何以及在何处调用Database.EnsureCreated和Database.Migrate?

2mbi3lxu  于 2023-02-17  发布在  .NET
关注(0)|答案(8)|浏览(232)

我有一个ASP.NETMVC6应用程序,我需要调用Database.EnsureCreatedDatabase.Migrate方法。
但我该打到哪里去呢?

14ifxucb

14ifxucb1#

我认为这是一个重要的问题,应该好好回答!

    • 什么是数据库. EnsureCreated?**

context.Database.EnsureCreated()是新的EF核心方法,可确保上下文的数据库存在。如果存在,则不执行任何操作。如果不存在,则创建数据库及其所有方案,并确保它与此上下文的模型兼容。

  • 注:* 此方法不使用迁移来创建数据库。此外,创建的数据库以后也不能使用迁移进行更新。如果目标是关系数据库并使用迁移,则可以使用DbContext.Database.Migrate()方法来确保创建数据库并应用所有迁移。
    • 我们是如何用EF6做到的**

context.Database.EnsureCreated()等同于下列EF 6方法:
1.程序包管理器控制台:

  • 启用迁移-启用自动迁移。添加迁移/更新数据库。*

1.来源代码:

  • 数据库. SetInitializer如果不存在则创建数据库 *

  • 使用DbMigrationsConfiguration并设置自动迁移已启用= true;*
    • 什么是数据库.迁移?**

将上下文的任何挂起迁移应用于数据库。如果数据库不存在,将创建该数据库。

    • 我们是如何用EF6做到的**

context.Database.Migrate()等同于下列EF 6方法:
1.程序包管理器控制台:

  • 更新-数据库-目标迁移 *

1.使用自定义DbMigrationsConfiguration:
启用自动迁移=假;或使用DbMigrator。

    • 结论**:

如果你使用的是migrations,则有context.Database.Migrate();如果你不需要migrations,而只需要一个快速的数据库(通常用于测试),则使用context.Database.EnsureCreated()/EnsureDeleted()。

ars1skjm

ars1skjm2#

根据James P和Bassam Alugili提供的信息,我最后做的是将以下代码行添加到Startup类(Startup.cs)中的Configure方法:

using (var scope = 
  app.ApplicationServices.CreateScope())
using (var context = scope.ServiceProvider.GetService<MyDbContext>())
    context.Database.Migrate();
3lxsmp7m

3lxsmp7m3#

通常,DbContext将被添加到Startup.ConfigureServices()中的依赖注入容器,如下所示:

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类的构造函数中,例如IConfigurationIWebHostEnvironment(3.0之前的版本中为IHostingEnvironment)、ILoggerFactoryIServiceProvider。请注意,后者是由宿主层构建的示例,仅包含启动应用程序所必需的服务。
为了调用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();
        }
    }
}

请记住,作为EF Core文档中引用的Bassam Alugili's answerDatabase.EnsureCreated()Database.Migrate()不应一起使用,因为其中一个确保现有迁移应用于数据库(如果需要,将创建该数据库)。另一个仅确保数据库存在,如果不存在,则创建一个反映您的DbContext的数据库。包括通过上下文中的API完成的任何播种。

bsxbgnwa

bsxbgnwa4#

作为一个前瞻,你应该阅读罗文米勒的this
... EnsureCreated完全绕过迁移,只为您创建架构,您不能将其与迁移混合使用。EnsureCreated专为测试或快速原型设计,您可以在每次删除并重新创建数据库时使用。如果您正在使用迁移,并希望在应用启动时自动应用它们,则可以改用context.Database.Migrate()
根据答案here,您需要将Globals.EnsureDatabaseCreated();添加到Startup.cs

Startup.cs中的启动功能:

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();
    }

要使用context.Database.Migrate(),请参见herehere

icnyk63a

icnyk63a5#

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddDbContext<YourDbContext>(option => option.UseSqlServer(@"Data source=(localdb)\ProjectModels;Initial Catalog=YourDb;Integrated Security=True"));

var app = builder.Build();

// Configure the HTTP request pipeline.
YourDbContext dbcontext = app.Services.GetRequiredService<YourDbContext>();
dbcontext.Database.EnsureCreated();
bxfogqkk

bxfogqkk6#

此外,如果在上下文的构造函数中调用它,可能会影响性能......在将EnsureCreated移到setup.cs实用程序之后,我注意到响应时间有了相当大的改进。
注意:我使用的是EFC和UWP。

42fyovps

42fyovps7#

如果您正在使用VS 2022/. Net Version 6,并且正在尝试找到创建数据库的方法,那么
执行以下步骤
从包管理器控制台通过包管理器添加Microsoft. EntityFramework. Tools引用
运行步骤1

    • 添加迁移初始迁移**

InitialMigration这里是自定义名称,您可以键入任何您想要的..让它运行
第二步

    • 更新数据库**

这将创建您的数据库。

mec1mxoz

mec1mxoz8#

我正在开发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();
}

context.Database.EnsureCreated()确保上下文的数据库存在。

  • 如果数据库存在并且具有任何表,则不执行任何操作。不执行任何操作以确保数据库架构与实体框架模型兼容。
  • 如果数据库存在但没有任何表,则使用实体框架模型来创建数据库模式。
  • 如果数据库不存在,则创建数据库并使用实体框架模型来创建数据库架构。

希望我帮上忙了。

相关问题