项目

切换到 EF Core Oracle 提供程序

本文档介绍如何为 **应用程序启动模板 ** 切换到 Oracle 数据库提供程序,该模板默认预配置了SQL Server 提供程序。

在切换提供程序之前,请确保您的Oracle版本为v12.2+。在较早版本的Oracle中,存在长标识符限制,阻止创建超过30字节的数据库表、列或索引。从 v12.2 开始,“标识符的最大长度增加到128字节”。v12.2及更高版本中,您可以无任何问题地使用ABP提供的数据库表、列和索引。

替换Volo.Abp.EntityFrameworkCore.SqlServer包

解决方案中的.EntityFrameworkCore项目依赖于Volo.Abp.EntityFrameworkCore.SqlServer NuGet包。移除此包并添加相同版本的Volo.Abp.EntityFrameworkCore.Oracle包。

替换模块依赖

.EntityFrameworkCore项目中找到您的项目名称EntityFrameworkCoreModule类,从DependsOn属性中移除typeof(AbpEntityFrameworkCoreSqlServerModule),添加typeof(AbpEntityFrameworkCoreOracleModule)

同时将using Volo.Abp.EntityFrameworkCore.SqlServer;替换为using Volo.Abp.EntityFrameworkCore.Oracle;

使用UseOracle()

在您的解决方案中找到UseSqlServer()调用,替换为UseOracle()。检查以下文件:

  • .EntityFrameworkCore项目中的您的项目名称EntityFrameworkCoreModule.cs。
  • .EntityFrameworkCore项目中的您的项目名称DbContextFactory.cs。

您的项目名称DbContextFactory.cs的CreateDbContext()方法中,将以下代码块

var builder = new DbContextOptionsBuilder<YourProjectNameDbContext>()
                .UseSqlServer(configuration.GetConnectionString("Default"));

替换为(仅将UseSqlServer(...)改为UseOracle(...)

var builder = new DbContextOptionsBuilder<YourProjectNameDbContext>()
                .UseOracle(configuration.GetConnectionString("Default"));

根据您的解决方案结构,您可能会发现需要更改更多代码文件。

更改连接字符串

Oracle连接字符串与SQL Server连接字符串不同。因此,检查解决方案中的所有appsettings.json文件并替换其中的连接字符串。有关Oracle连接字符串选项的详细信息,请参阅connectionstrings.com

您通常需要更改.DbMigrator.Web项目中的appsettings.json,但这取决于您的解决方案结构。

重新生成迁移

启动模板默认使用 Entity Framework Core的Code First Migrations 。 EF Core迁移依赖于所选的DBMS提供程序。更改DBMS提供程序可能与现有迁移不兼容。

  • 删除.EntityFrameworkCore项目下的Migrations文件夹并重新构建解决方案。
  • 在Package Manager Console窗口中运行Add-Migration "Initial"(在解决方案资源管理器中选择.DbMigrator(或.Web)项目作为启动项目,并在Package Manager Console中选择.EntityFrameworkCore项目作为默认项目)。

这将为Oracle搭建一个新的迁移。

运行.DbMigrator项目以创建数据库、应用更改并播种初始数据。

修复ORA-12899:列的值太大

创建迁移时,Oracle将字符串限制为NVARCHAR2(2000)。某些实体属性可能会超出此限制。您可以检查ABP模块实体中已知和报告的可能超出此限制的属性。为防止此问题,您需要先将string类型转换为long类型,并生成新的迁移。然后将long类型转换为具有最大长度的clob类型。

修复ORA-00904:"FALSE":无效标识符

在23ai版本中,Oracle添加了新的OracleSQLCompatibility枚举值:

  • OracleSQLCompatibility.DatabaseVersion19
  • OracleSQLCompatibility.DatabaseVersion21
  • OracleSQLCompatibility.DatabaseVersion23

默认情况下,枚举值将与ODP.NET版本号匹配。对于ODP.NET 23,枚举为OracleSQLCompatibility.DatabaseVersion23

在DB 23ai中,支持BOOLEAN列和原生JSON列。因此,Oracle EF Core 8.23.40在其SQL中使用这些功能,当设置OracleSQLCompatibility.DatabaseVersion23或未设置值时。如果您希望恢复到19c兼容行为,请使用OracleSQLCompatibility.DatabaseVersion19值。

有关更多详细信息,请参阅以下问题: https://github.com/oracle/dotnet-db-samples/issues/377#issuecomment-2096419703

如果您想更改OracleSQLCompatibility值,需要在AbpDbContextOptionsMyProjectNameDbContextFactory文件中进行更改。

public override void ConfigureServices(ServiceConfigurationContext context)
{ 
    Configure<AbpDbContextOptions>(options =>   
    {   
        options.UseOracle(x => x.UseOracleSQLCompatibility(OracleSQLCompatibility.DatabaseVersion19)); 
    });
}
public MyProjectNameDbContext CreateDbContext(string[] args)
{
    var configuration = BuildConfiguration();

    AbpSolution4EfCoreEntityExtensionMappings.Configure();

    var builder = new DbContextOptionsBuilder<MyProjectNameDbContext>()
        .UseOracle(configuration.GetConnectionString("Default"), x =>
        {
            x.UseOracleSQLCompatibility(OracleSQLCompatibility.DatabaseVersion19);
        });

    return new MyProjectNameDbContext(builder.Options);
}

第一次迁移

更新您的应用程序DbContext的OnModelCreating方法:

protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        /* 将模块包含到您的迁移数据库上下文中 */

        builder.Entity<OpenIddictToken>(b =>
        {
            b.Property(q => q.Payload).HasColumnType("long").HasMaxLength(int.MaxValue);
        });
        
        builder.Entity<AuditLog>(b =>
        {
            b.Property(x => x.Exceptions).HasColumnType("long").HasMaxLength(int.MaxValue);
        });
        
        builder.Entity<AuditLogAction>(b =>
        {
            b.Property(x => x.Parameters).HasColumnType("long").HasMaxLength(int.MaxValue);
        });
        
        /* 在此处配置您自己的表/实体 */
    }

使用dotnet工具在您的解决方案的EntityFrameworkCore层下创建新的迁移:dotnet ef migrations add Oracle_Long_Conversion

第二次迁移

更新您的应用程序DbContext的OnModelCreating方法:

protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        /* 将模块包含到您的迁移数据库上下文中 */

        builder.Entity<OpenIddictToken>(b =>
        {
            b.Property(q => q.Payload).HasColumnType("clob").HasMaxLength(4000);
        });
        
        builder.Entity<AuditLog>(b =>
        {
            b.Property(x => x.Exceptions).HasColumnType("clob").HasMaxLength(4000);
        });
        
        builder.Entity<AuditLogAction>(b =>
        {
            b.Property(x => x.Parameters).HasColumnType("clob").HasMaxLength(4000);
        });
        
        /* 在此处配置您自己的表/实体 */
    }

使用dotnet工具在您的解决方案的EntityFrameworkCore层下创建新的迁移:dotnet ef migrations add Oracle_Clob_Conversion

运行DbMigrator(或使用dotnet工具)以迁移Oracle数据库。

运行应用程序

一切准备就绪。只需运行应用程序并享受编码。

在本文档中