如何将OracleConfiguration参数融入EF Core Oracle数据库Scaffolding连接字符串?
问题
我有一个.NET Core 6控制台应用,通过以下配置读取Oracle数据库数据,运行完全正常:
var connectionString = "User Id=MY_USER;Password=MY_PASSWORD;Data Source=MY_DATASOURCE;"; OracleConfiguration.DirectoryServers = "(my.directory.server:123:456)"; OracleConfiguration.DirectoryServerType = "AD"; OracleConfiguration.DefaultAdminContext = "cn=my_cn,dc=my_dc_1,dc=my_dc_2"; OracleConfiguration.NamesDirectoryPath = "(LDAP)"; OracleConfiguration.SqlNetAuthenticationServices = "(NONE,NTS)"; _ = services.AddDbContext<DbContext, MyDbContext>(options => { _ = options.UseOracle(connectionString); });
执行以下EF Core脚手架命令时,返回错误:ORA-12154: TNS:could not resolve the connect identifier specified
dotnet-ef dbcontext scaffold "User Id=MY_USER;Password=MY_PASSWORD;Data Source=MY_DATASOURCE;" "Oracle.EntityFrameworkCore"
原因是dotnet-ef命令未加载代码中配置的OracleConfiguration参数,请问如何将这些自定义参数融入到脚手架命令的连接逻辑中?
解决方案
方法1:将配置参数直接追加到连接字符串
Oracle支持将OracleConfiguration的参数作为键值对直接添加到连接字符串中,你可以把需要的参数拼接到脚手架命令的连接字符串里,示例如下:
dotnet-ef dbcontext scaffold "User Id=MY_USER;Password=MY_PASSWORD;Data Source=MY_DATASOURCE;Directory Servers=(my.directory.server:123:456);Directory Server Type=AD;Default Admin Context=cn=my_cn,dc=my_dc_1,dc=my_dc_2;Names Directory Path=(LDAP);Sql Net Authentication Services=(NONE,NTS);" "Oracle.EntityFrameworkCore"
注意参数名需保留空格,比如Directory Servers对应代码中的OracleConfiguration.DirectoryServers。
方法2:使用配置文件(推荐)
- 在项目根目录创建或修改
appsettings.json,添加Oracle配置项:
{ "ConnectionStrings": { "OracleDb": "User Id=MY_USER;Password=MY_PASSWORD;Data Source=MY_DATASOURCE;" }, "Oracle": { "DirectoryServers": "(my.directory.server:123:456)", "DirectoryServerType": "AD", "DefaultAdminContext": "cn=my_cn,dc=my_dc_1,dc=my_dc_2", "NamesDirectoryPath": "(LDAP)", "SqlNetAuthenticationServices": "(NONE,NTS)" } }
- 创建设计时DbContext工厂类,用于脚手架命令读取配置:
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; using Microsoft.Extensions.Configuration; using Oracle.EntityFrameworkCore; using Oracle.ManagedDataAccess.Client; using System.IO; public class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext> { public MyDbContext CreateDbContext(string[] args) { var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); // 加载Oracle配置参数 OracleConfiguration.DirectoryServers = configuration["Oracle:DirectoryServers"]; OracleConfiguration.DirectoryServerType = configuration["Oracle:DirectoryServerType"]; OracleConfiguration.DefaultAdminContext = configuration["Oracle:DefaultAdminContext"]; OracleConfiguration.NamesDirectoryPath = configuration["Oracle:NamesDirectoryPath"]; OracleConfiguration.SqlNetAuthenticationServices = configuration["Oracle:SqlNetAuthenticationServices"]; var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>(); optionsBuilder.UseOracle(configuration.GetConnectionString("OracleDb")); return new MyDbContext(optionsBuilder.Options); } }
- 执行脚手架命令时,直接引用配置文件中的连接字符串即可:
dotnet-ef dbcontext scaffold "Name=ConnectionStrings:OracleDb" "Oracle.EntityFrameworkCore"
这种方法避免了命令行暴露敏感信息,配置也更易于维护。
方法3:使用环境变量
执行脚手架命令前,先设置对应Oracle环境变量(参数名需转换为大写并添加ORA_前缀):
- Windows命令行:
set ORA_DIRECTORY_SERVERS=(my.directory.server:123:456) set ORA_DIRECTORY_SERVER_TYPE=AD set ORA_DEFAULT_ADMIN_CONTEXT=cn=my_cn,dc=my_dc_1,dc=my_dc_2 set ORA_NAMES_DIRECTORY_PATH=(LDAP) set ORA_SQLNET_AUTHENTICATION_SERVICES=(NONE,NTS)
- Linux/macOS终端:
export ORA_DIRECTORY_SERVERS="(my.directory.server:123:456)" export ORA_DIRECTORY_SERVER_TYPE="AD" export ORA_DEFAULT_ADMIN_CONTEXT="cn=my_cn,dc=my_dc_1,dc=my_dc_2" export ORA_NAMES_DIRECTORY_PATH="(LDAP)" export ORA_SQLNET_AUTHENTICATION_SERVICES="(NONE,NTS)"
设置完成后,再执行原脚手架命令即可。
内容的提问来源于stack exchange,提问作者papps
相关产品推荐
相关产品推荐

