【问题标题】:Database creation with EF Core + Code First + migrations使用 EF Core + Code First + 迁移创建数据库
【发布时间】:2020-12-03 11:49:06
【问题描述】:

对于具有代码优先和迁移的 Entity Framework Core 应用程序, 如果数据库不存在,我无法创建它。

我的第一个电话是:

using (MyDbContext context = new MyDbContext())
{
    context.Database.Migrate();
}

它运行被覆盖的方法:

// 1
protected override void OnConfiguring(DbContextOptionsBuilder optionBuilder)
{
    optionBuilder.UseOracle($"ENLIST=dynamic;USER ID={UserId};POOLING=True;CONNECTION TIMEOUT=15;PASSWORD={Pwd};DATA SOURCE=localhost:1521/xe;CONNECTION LIFETIME=0");
}

// 2
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDefaultSchema(UserId);
}

并抛出以下异常:

System.NotSupportedException:'所需用户不存在或提供的用户名/密码无效'

我期待数据库和用户将在HasDefaultSchema 调用中创建。 在这种情况下我缺少什么?

【问题讨论】:

标签: c# oracle entity-framework-core ef-code-first entity-framework-migrations


【解决方案1】:

很遗憾,optionBuilder 中的UseOracle 方法不支持架构不存在时创建架构。

原因是 Sql Server 或 Postgres 中的架构与 Oracle 之间存在特定差异。

EnsureSchemaOperation 类

用于确保架构存在的 MigrationOperation。也就是说,当且仅当架构不存在时才会创建它。

[System.Diagnostics.DebuggerDisplay("CREATE SCHEMA {Name}")]
public class EnsureSchemaOperation : 
Microsoft.EntityFrameworkCore.Migrations.Operations.MigrationOperation

该方法使用语法create schema,可应用于某些数据库引擎,但不适用于Oracle。原因如下:

CREATE SCHEMA 语句实际上并未在 Oracle 中创建模式。 CREATE SCHEMA 语句仅用于在单个 SQL 语句中在您的模式中创建对象(即:表、视图),而不必发出单独的 CREATE TABLE 和 CREATE VIEW 语句。如果您使用 CREATE SCHEMA 语句,您可以将它们作为一个单元来控制。

Oracle 模式类似于 Windows 操作系统中的“我的文档”文件夹。用户可以授予其他用户查看其架构中内容的权限,但 Oracle 架构本质上是用户的工作区。

MS SQL Server 的架构是命名空间。虽然您可以拥有会计和营销模式,但它们并没有与单个用户紧密耦合。会计模式中的对象包含会计信息,营销模式中的对象包含营销信息。

Oracle 架构与用户紧密耦合,MS SQL Server 架构主要用于分类。

在 Oracle 中,模式始终是用户。您可以创建两个具有相同名称的不同表,属于不同的用户/模式。在 SQL Server 中,架构和用户是不同的东西。用户仅用于登录和定义权限。

我相信微软没有在受影响类的对应方法中实现CREATE USER xxx

【讨论】:

    【解决方案2】:

    您是否检查过迁移是否包括架构的创建?

    根据我的经验,一些数据库连接器默认包括自动创建架构,而有些则不包括,例如 mysql 和 ms 会,但 MariaDB 的相同代码需要在之前创建架构。

    【讨论】:

    • 所以您必须自己在迁移中编写架构创建?我的第一次迁移包含migrationBuilder.EnsureSchema(name: "MySchema"),但似乎没有创建它。
    【解决方案3】:

    提供的用户名和密码似乎有问题。请与您正在使用的 oracle 实例交叉检查用户名和密码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-08
      • 2013-04-20
      • 2015-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-18
      • 1970-01-01
      相关资源
      最近更新 更多