繁体   English   中英

如何首先停止实体框架代码运行“CREATE SCHEMA IF NOT EXISTS”

[英]How to Stop the Entity Framework Code First from running “CREATE SCHEMA IF NOT EXISTS”

以下是有关我们的技术开发环境的信息:

  • .NET 核心3.1
  • PostgreSQL 14.2,由 Visual C++ build 1914 编译,64 位
  • EntityFramework.Functions 版本=1.5.0
  • Microsoft.EntityFrameworkCore.Design 版本=5.0.17
  • Microsoft.EntityFrameworkCore.Tools 版本=5.0.17
  • Npgsql.EntityFrameworkCore.PostgreSQL 版本=5.0.10

我们正在使用 PostgreSQL 用户帐户,该帐户非常受限制,因为我们只希望该帐户创建典型的数据库对象(即表、视图、函数、过程等),但我们不希望该帐户创建数据库模式。 这只是为了安全,让我们的环境更加防弹。

public class DatabaseContext : DbContext
{
    public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
         modelBuilder.HasDefaultSchema(Constants.SchemaName);
         base.OnModelCreating(modelBuilder);
         modelBuilder.ApplyConfiguration(new SuperMarketEntityTypeMap());
    } 

    public DbSet<SuperMarket> supermarkets { get; set; }

    public void SetCommandTimeout(int? timeout)
    {
         this.Database.SetCommandTimeout(timeout);
    }

    public override void Dispose()
    {
        base.Dispose();
    }
}

public class DatabaseContextFactory : IDesignTimeDbContextFactory<DatabaseContext>
{
     public DatabaseContext CreateDbContext(string[] args)
     {
         var optionsBuilder = new DbContextOptionsBuilder<DatabaseContext>();
         optionsBuilder.UseNpgsql(x => x.MigrationsHistoryTable(
         HistoryRepository.DefaultTableName, Constants.SchemaName));

         return new DatabaseContext(optionsBuilder.Options);
    }
}

在我的 PowerShell 命令行中,当我运行如下更新时,它会在尝试“如果不存在时创建模式”时抛出错误,因为我们没有授予 PostgreSQL 用户帐户创建数据库模式的权限。 我们只希望所述用户帐户创建典型的数据库对象(即表、视图、函数、过程等):

dotnet ef database update –connection “Blah Blah Blah Connection String Blah Blah Blah” 

Build started... 
Build succeeded.

Failed executing DbCommand (115ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] CREATE SCHEMA IF NOT EXISTS supermarkets_schema; CREATE TABLE sendgrid_status."__EFMigrationsHistory" (
 "MigrationId" character varying(150) NOT NULL,
 "ProductVersion" character varying(32) NOT NULL,
 CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId") );

有人可以发布带有代码和/或命令行执行 arguments 和/或配置更改的响应,这些更改将显示我如何阻止实体框架代码优先运行“CREATE SCHEMA IF NOT EXISTS”吗?

本质上,在下面的帖子中,开发人员在 NpgsqlMigrationsSqlGenerator 的自定义子类中使用一个空方法覆盖了 NpgsqlMigrationsSqlGenerator 的生成,该子类称为 MyMigrationsSqlGenerator

(技术参考: https://github.com/npgsql/efcore.pg/issues/1770

---摘自上面的帖子----------------------------

遇到了此处描述的相同问题(我们将每个应用程序映射到一个单独的模式,模式之间严格隔离)。 感谢 Shay 的提示,我能够解决它:

 public class MyMigrationsSqlGenerator: NpgsqlMigrationsSqlGenerator { public MyMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, INpgsqlOptions npgsqlOptions): base(dependencies, npgsqlOptions) { } protected override void Generate(EnsureSchemaOperation operation, IModel model, MigrationCommandListBuilder builder) { // don't generate schema operations as they are not permitted with our current permissions setup } }

然后将其与以下内容联系起来:

 .ReplaceService<IMigrationsSqlGenerator, NpgsqlMigrationsSqlGenerator, MyMigrationsSqlGenerator>()

---摘自上面的帖子----------------------------

为了详细说明上面 ReplaceService 代码行的位置,它位于我的 IDesignTimeDbContextFactory 实现中:

 public class DatabaseContextFactory: IDesignTimeDbContextFactory<DatabaseContext> { public DatabaseContext CreateDbContext(string[] args) { var optionsBuilder = new DbContextOptionsBuilder<DatabaseContext>(); optionsBuilder.ReplaceService<IMigrationsSqlGenerator, NpgsqlMigrationsSqlGenerator, MyMigrationsSqlGenerator>().UseNpgsql( x => x.MigrationsHistoryTable( HistoryRepository.DefaultTableName, "Blah Blah Blah Database Schema Name Blah Blah")); return new DatabaseContext(optionsBuilder.Options); } }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM