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

时间:2017-07-17 08:18:07

标签: c# entity-framework orm .net-core .net-standard

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

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

Ticker.Add(...);
dbctx.SaveChanges(); <== exception

异常结果:

  

System.Data.SqlClient.SqlException:无效的对象名称&#39; Ticker&#39;

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

==编辑==

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

4 个答案:

答案 0 :(得分:2)

这里有几个选项。最简单的方法是:

MyContext.Database.CreateIfNotExists();

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

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

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

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

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

编辑:

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

Database.SetInitializer<MyContext>(new MigrateDatabaseToLatestVersion<MyContext, Config>());

答案 1 :(得分:1)

我的猜测是您的上下文定义错误。也许您忘记了将DbSet添加到上下文实现中?

下面的代码运行良好,老实说,我更喜欢在实际的DBContext实现的构造函数中使用ConfirmCreated()。

internal class AZSQLDbContext : DbContext
{
    public AZSQLDbContext() {
        this.Database.EnsureCreated();
    }

    internal DbSet<TaskExecutionInformation> TaskExecutionInformation { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var dbUser = "your-user";
        var dbPW = "your-pw";
        optionsBuilder.UseSqlServer(
            $"Server=tcp:sample-sql.database.windows.net,1433;Initial Catalog=sample-db;Persist Security Info=False;User ID={dbUser};Password={dbPW};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;");
    }
}

TaskExecutionInformation只是PoCo,可以是任何东西。不过,如果您需要一些指导,请参阅下文。

public class TaskExecutionInformation
{
    public Guid Id { get; set; }
    public string Status { get; set; }
    public int Duration { get; set; }
}

答案 2 :(得分:1)

在Entity Framework Core中,可以使用以下代码在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.
}
当数据库已经存在时,

Database.EnsureCreated()不会创建架构(因此您的表)。这就是您得到该例外的原因。 您可以检查该方法的documentation

答案 3 :(得分:0)

在您的Startup.cs中

import * as React from 'react'

并确保您的AppDBContext中的连接字符串正确无误(MySQL XAMPP)

library(XLConnect)

testDir <- "C:\\your_path_here\\"

re_file <- ".+\\.xls.?"
testFiles <- list.files(testDir, re_file, full.names = TRUE)

# This function rbinds in a single dataframe
# the content of multiple sheets in the same workbook
# (assuming that all the sheets have the same column types)
rbindAllSheets <- function(file) {
  wb <- loadWorkbook(file)
  sheets <- getSheets(wb)
  do.call(rbind,
          lapply(sheets, function(sheet) {
            readWorksheet(wb, sheet)
          })
  )
}

# Getting a single dataframe for all the Excel files
result <- do.call(rbind, lapply(testFiles, rbindAllSheets))