sqlite 如何在第一次运行时自动创建数据库?

brccelvz  于 2022-11-14  发布在  SQLite
关注(0)|答案(6)|浏览(231)

我要移植到.NET Core的应用程序将使用带有SQLite的EF Core。我想自动创建数据库和表格时,该应用程序是第一次运行。根据文档,这是使用手动命令完成的:

dotnet ef migrations add MyFirstMigration

dotnet ef database update

我不希望最终用户输入这些,但更喜欢应用程序来创建和设置第一次使用的数据库。对于EF 6,有:

Database.SetInitializer(new CreateDatabaseIfNotExists<MyContext>());

但我找不到任何与EF Core类似的产品。我已经有了模型类,所以我可以编写代码来基于模型初始化数据库,但如果框架自动完成这一点会更容易。我不想自动构建模型或迁移,只想在新数据库中创建表。
EF Core中是否缺少自动创建表功能?

m528fe3b

m528fe3b1#

如果您已经创建了迁移,您可以在Startup.cs中执行它们,如下所示。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
 {
      using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
      {
            var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
            context.Database.Migrate();
      }
      
      ...

这将使用您添加的迁移创建数据库和表。
如果您没有使用实体框架迁移,而是只需要在第一次运行时创建与上下文类中完全相同的DbContext模型,那么您可以使用:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
 {
      using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
      {
            var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
            context.Database.EnsureCreated();
      }
      
      ...

取而代之的是。
如果您需要在确保创建数据库之前将其删除,请致电:

context.Database.EnsureDeleted();

就在您调用**EnsureCreated()**之前
改编自:http://docs.identityserver.io/en/latest/quickstarts/7_entity_framework.html?highlight=entity

gtlvzcf8

gtlvzcf82#

我的回答与Ricardo的答案非常相似,但我觉得我的方法更简单一些,因为他的using函数中有太多事情要做,我甚至不确定它在较低级别上到底是如何工作的。
因此,对于那些想要一个简单、干净的解决方案来为您创建一个数据库,使您确切地知道幕后发生的事情的人来说,这是适合您的:

public Startup(IHostingEnvironment env)
{
    using (var client = new TargetsContext())
    {
        client.Database.EnsureCreated();
    }
}

这基本上意味着在您创建的DbContext中(在本例中,我的TargetsContext称为TargetsContext),您可以使用DbContext的一个示例来确保在应用程序中运行Startup.cs时创建在类中定义的表。

szqfcxe2

szqfcxe23#

如果通过Startup.cs中的CONFIGURE参数列表获取上下文,则可以这样做:

public void Configure(IApplicationBuilder app, IHostingEnvironment env,  LoggerFactory loggerFactory,
    ApplicationDbContext context)
 {
      context.Database.Migrate();
      ...
2wnc66cl

2wnc66cl4#

对于EF Core 2.0+,我不得不采取不同的方法,因为他们改变了API。从2019年3月起,微软建议您将数据库迁移代码放在应用程序入门类中,但不在网络主机构建代码之外。

public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateWebHostBuilder(args).Build();
        using (var serviceScope = host.Services.CreateScope())
        {
            var context = serviceScope.ServiceProvider.GetRequiredService<PersonContext>();
            context.Database.Migrate();
        }
        host.Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}
iyzzxitl

iyzzxitl5#

如果您尚未创建迁移,则有两种选择
1.从应用程序Main创建数据库和表:

var context = services.GetRequiredService<YourRepository>();
context.Database.EnsureCreated();

2.如果数据库已存在,则创建表:

var context = services.GetRequiredService<YourRepository>();
context.Database.EnsureCreated();
RelationalDatabaseCreator databaseCreator =
(RelationalDatabaseCreator)context.Database.GetService<IDatabaseCreator>();
databaseCreator.CreateTables();

多亏了布比的answer

bn31dyow

bn31dyow6#

如果您希望同时创建EnsureCreate和迁移EnsureEnsure.exe,请使用以下代码:

using (var context = new YourDbContext())
            {
                if (context.Database.EnsureCreated())
                {
                    //auto migration when database created first time

                    //add migration history table

                    string createEFMigrationsHistoryCommand = $@"
USE [{context.Database.GetDbConnection().Database}];
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
CREATE TABLE [dbo].[__EFMigrationsHistory](
    [MigrationId] [nvarchar](150) NOT NULL,
    [ProductVersion] [nvarchar](32) NOT NULL,
 CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY CLUSTERED 
(
    [MigrationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY];
";
                    context.Database.ExecuteSqlRaw(createEFMigrationsHistoryCommand);

                    //insert all of migrations
                    var dbAssebmly = context.GetType().GetAssembly();
                    foreach (var item in dbAssebmly.GetTypes())
                    {
                        if (item.BaseType == typeof(Migration))
                        {
                            string migrationName = item.GetCustomAttributes<MigrationAttribute>().First().Id;
                            var version = typeof(Migration).Assembly.GetName().Version;
                            string efVersion = $"{version.Major}.{version.Minor}.{version.Build}";
                            context.Database.ExecuteSqlRaw("INSERT INTO __EFMigrationsHistory(MigrationId,ProductVersion) VALUES ({0},{1})", migrationName, efVersion);
                        }
                    }
                }
                context.Database.Migrate();
            }

相关问题