在EF Core中的运行时创建表

时间:2016-07-22 18:02:52

标签: entity-framework-core

我知道我可以使用以下命令添加新迁移并创建数据库:

dotnet ef migrations add MigrationName -c DbContextName
dotnet ef database update -c DbContextName

但我需要在运行时创建我的数据库/表。

首先,我尝试通过覆盖OnModelCreating来做到这一点,但我失败了。它返回给我一个错误,指出表尚未创建

这是我的dbcontext类

public class AimeLoggerContext : DbContext
    {

        public AimeLoggerContext(DbContextOptions<AimeLoggerContext> options)
            : base(options)
        {

            Database.Migrate();
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

            modelBuilder.Entity("Aime.Logger.Loggers.Database.Model.Log", b =>
            {
                b.Property<int>("Id")
                  .ValueGeneratedOnAdd();
                b.Property<DateTime>("Datetime");
                b.HasKey("Id");
                b.ToTable("Logs");

            });

            base.OnModelCreating(modelBuilder);

        }

        public DbSet<Log> Logs { get; set; }


    }

任何想法?

3 个答案:

答案 0 :(得分:13)

如果您需要创建模型表,如果在您的数据库中还有其他表可以使用

RelationalDatabaseCreator databaseCreator = 
    (RelationalDatabaseCreator) context.Database.GetService<IDatabaseCreator>();
databaseCreator.CreateTables();

答案 1 :(得分:6)

在我潜水之前

如果您真的想做正确的事情,那么您可能应该使用Migrate()而不是确保对象CreateCreate(),因为后者意味着如果您想进行迁移,则会遇到问题。

您希望在运行应用程序时创建数据库和表的事实,这意味着您可能更倾向于迁移脚本和工作流的代码优先方法,而不是数据库优先类型的数据库脚本。 / p>

所以我认为

  • 您想使用代码优先方法
  • 您要使用EF Core迁移
  • 您希望这些迁移在启动应用程序时自动发生。
  • 您想以正确的方式做到这一点!

我刚刚设法做到这一点(我的工作是使用Postgres,但一切都应该非常接近,因为我看到了MS Sql的示例,它们非常相似,唯一的区别是useSqlServerUseNpgsql或类似的琐碎差异。

在努力阅读有关StackOverflow的各种文章之后,这些文章只是最大图片的一小段,我终于设法使它运转良好,正常运行,甚至优雅。我关注了这篇文章here

我做过几件事,但不确定什么才是使它正常工作的东西,但我相信此列表足够小,不能令人满意。

>

这就是我所做的

  1. 通过遵循this article here by MicroSoft

    ,确保已安装了powershell Cli工具。
  2. 我在cmd.exe dotnet tool install --global dotnet-ef

    中运行了此文件
  3. 打开VS Package Manager控制台,您可以通过在VS 2019顶部搜索框中键入Package Manager控制台进行访问(

enter image description here

  1. 在其中键入以下命令
Install-Package Microsoft.EntityFrameworkCore.Tools
Update-Package Microsoft.EntityFrameworkCore.Tools

我的存储库代码与Web App项目位于不同的项目中,所以对我来说,我遇到了一些错误。我必须做以下事情

我尝试在我的存储库项目上运行EF Migrate命令,因为它无法在WebAPI项目中使用

dotnet ef migrations add InitialCreate --project .\DilaRepository\DilaRepository.csproj

  • 控制台抱怨

您的启动项目“ DilaRepository”未引用Microsoft.EntityFrameworkCore.Design

因此,在我收到这些消息的地方,我添加了nuget软件包,从而摆脱了这些错误。我不知道是否需要这样做,因为最后我得到了EF Migrate命令,该命令在WebApi项目中起作用,该项目包含startup.cs和program.cs

这是我需要做的工作

在我的startup.cs文件中,我有这个文件(相当简单,您将在所有文章中看到它)

public void ConfigureServices(IServiceCollection services)
{
   ...
   services.AddEntityFrameworkNpgsql().AddDbContext<DilaDbContext>(opt => 
            opt.UseNpgsql(
                Configuration.GetConnectionString("DefaultConnection"), 
                b => b.MigrationsAssembly("DilaAPI")
            ));

在我读过的任何文章中都没有显示MigrationAssembly,在这里我使用的是其中执行的程序集的名称,因此它本身无法弄清楚似乎有点奇怪。 ,所以也许我做错了这一点。我相信我从运行add-migration initial收到的错误消息之一告诉我,我需要这样做,而在此之后它就起作用了。

**将这个连接字符串添加到appsettings.json中是非常重要的(并且在其中可以在运行时读取正确的连接字符串,因为可以有多个(例如appsettings.Development.json)**)

在命令提示符下运行add-migration命令时,这是必需的。这在我的WebAPI应用程序中创建了一个迁移文件夹,其中包含一些用于迁移的内容,但是该文件夹未在我的数据库上执行。我不确定它是否确实应该,但是我将解释我最终如何在数据库上执行它。

执行以下命令以生成迁移内容

add-migration initial

如果它不起作用并且出现一些错误,您可以尝试以下一些方法

我们的目标项目'DilaAPI'与您的迁移程序集'DilaRepository'不匹配。更改目标项目或更改迁移程序集。 通过使用DbContextOptionsBuilder更改迁移程序集。例如。 options.UseSqlServer(connection,b => b.MigrationsAssembly(“ DilaAPI”))

这就是最初指示我在startup.cs中添加程序集的内容。这实际上是一条非常好的错误消息,因为它告诉您确切需要进行哪些操作才能修复它并起作用

错误MSB4057:项目中不存在目标“ GetEFProjectMetadata”。

这发生在我要么

  • 在错误的目录中执行了此操作
  • 在解决方案文件中对此进行了说明

最后,我需要在WebApi项目的csproj上运行此程序才能工作,您可能必须从软件包管理器控制台cd到目录,或者可以使用{{ 1}}选项,例如--project就我而言

如果没有按照上述步骤正确安装EF工具,您可能还会遇到一些错误

这是它产生的东西的图片

enter image description here

最后一件事

在startup.cs中将其添加到配置方法中

--project .\DilaApi\DilaApi.csproj

如果在启动时执行所有其他操作,那么实际上将执行public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DilaDbContext context) ... context.Database.Migrate(); 命令预先生成的迁移。

现在启动您的应用,它应该看起来像这样

enter image description here

我抱怨我做错了什么,但是我遵循了Microsoft,EF Core和Postgres的文章,所以我不确定为什么,但是它起作用了。如果有人知道这是为什么,以及我如何摆脱该警告,我将不胜感激。也许我们应该告诉他们更新文档,以便他们的示例也不会导致此警告。

这对我的数据库做了什么

  • 创建数据库
  • 创建表格

魔术!!! ?‍♀️

enter image description here

这是非常了不起的,因为它使用臭名昭著的 Convention over Configuration 来知道我的表应该被称为Word,而数据库的名称应该是Context的名称和Entities的名称。 / p>

很抱歉,答案很长,但是花了我几个小时才能完成这项工作,所以我想与大家分享我的战争故事,希望其他人能比我更快地完成工作

答案 2 :(得分:4)

而不是DbContext.Database.Migrate()我应该使用DbContext.Database.EnsureCreated()方法。