如果表不存在,创建一个表?

flu*_*ter 10 c# orm entity-framework .net-core .net-standard

使用 Entity Framework Core,如果表尚不存在,有没有办法创建它?即使EnsureCreated在上下文中调用也会抛出异常:

DbSet<Ticker> Ticker { get; set }
Database.EnsureCreated();

Ticker.Add(...);
dbctx.SaveChanges(); <== exception
Run Code Online (Sandbox Code Playgroud)

结果异常:

System.Data.SqlClient.SqlException: 无效的对象名称 'Ticker'

有没有办法Ticker在插入数据之前创建表?

== 编辑==

这个问题不是创建/迁移整个数据库,数据库一直存在,它的大部分表也存在,但有些表可能不存在。所以我只需要在运行时创建一两个表。

Ano*_*uar 6

在实体框架核心(版本 2.2.4)中,如果表不存在,您可以在 DbContext 中使用以下代码在数据库中创建表:

try
{
    var databaseCreator = (Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator);
    databaseCreator.CreateTables();
}
catch (System.Data.SqlClient.SqlException)
{
    //A SqlException will be thrown if tables already exist. So simply ignore it.
}
Run Code Online (Sandbox Code Playgroud)

当数据库已经存在时,Database.EnsureCreated() 不会创建架构(所以你的表)。这就是你得到那个例外的原因。您可以查看该方法的文档

PS:如果在新版本的 Entity Framework Core 中发生变化,请确保捕获正确的异常。


sty*_*ybl 1

您在这里有几个选择。最简单的是:

MyContext.Database.CreateIfNotExists();
Run Code Online (Sandbox Code Playgroud)

或者,通过将其放入上下文的构造函数中来执行初始化样式:

Database.SetInitializer<MyContext>(new CreateDatabaseIfNotExists<MyContext>());
Run Code Online (Sandbox Code Playgroud)

然而,这两种方法都要求您在每次修改模型并需要重新创建数据库时手动删除架构。如果您不想这样做,可以使用以下初始化:

Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
Run Code Online (Sandbox Code Playgroud)

每次运行程序时,这都会根据数据库检查您的模型,如果模型已被修改,则会自动删除并重新创建数据库。

编辑:

如果您不想删除数据库,而只是更新它,那么您可以使用以下初始化:

Database.SetInitializer<MyContext>(new MigrateDatabaseToLatestVersion<MyContext, Config>());
Run Code Online (Sandbox Code Playgroud)

  • @fluter 是的,我没有注意到你正在使用 EF Core。不幸的是,MS 已经删除了 EF Core 中的自动迁移,并且根本不打算实现它们。 (3认同)
  • 我不创建数据库,数据库始终存在,如果表不存在,我只需要创建一个表。 (2认同)