当前位置: 首页 > news >正文

FrameWork4.5 项目下使用EF6 同一项目操作多种数据库

本贴用于记录 EF6不通过配置文件去获取连接字符串也可以成功一个项目同时访问多种数据库的情况

项目下包含
// Contexts/BaseDbContext.cs
internal class BaseDbContext : DbContext
{
public BaseDbContext(string connectionString) : base(connectionString) { }
}

[DbConfigurationType(typeof(SqlServerDbConfiguration))]
internal class SqlServerContext : DbContext
{
static SqlServerContext() {

     Console.WriteLine("SqlServerContext 静态构造函数已执行");}public SqlServerContext(string connectionString)

: base(EfConnectionHelper.CreateNamedConnectionString(
connectionString, "System.Data.SqlClient"))
{ }
//public SqlServerContext(string connectionString) : base(connectionString) { }
//public SqlServerContext() : base("name=SqlServerDbContext") { }
}

[DbConfigurationType(typeof(OracleDbConfiguration))]
internal class OracleContext : DbContext
{
static OracleContext() {

     Console.WriteLine(" OracleContext 静态构造函数已执行");}public OracleContext(string connectionString): base(EfConnectionHelper.CreateNamedConnectionString(connectionString, "Oracle.ManagedDataAccess.Client")){ }//public OracleContext(string connectionString) : base(connectionString) { }//public OracleContext() : base("name=OracleDbContext") { }

}

internal class SqliteContext : BaseDbContext
{
public SqliteContext(string connectionString) : base(connectionString) { }
}

// 定义配置类(保持不变)
internal class SqlServerDbConfiguration : DbConfiguration
{
public SqlServerDbConfiguration()
{
SetProviderServices("System.Data.SqlClient",
System.Data.Entity.SqlServer.SqlProviderServices.Instance);
SetDefaultConnectionFactory(new SqlConnectionFactory());
Console.WriteLine(" SqlServerDbConfiguration 已执行");
}
}

internal class OracleDbConfiguration : DbConfiguration
{
public OracleDbConfiguration()
{
SetProviderServices("Oracle.ManagedDataAccess.Client",
Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices.Instance);
// Oracle 不需要默认连接工厂(通常由连接字符串决定)
Console.WriteLine(" OracleDbConfiguration 已执行");
}
}

public static class DatabaseFactory
{
public static IDatabaseService CreateService(DatabaseType dbType, string connectionString)
{
return new DatabaseService(dbType, connectionString);
}

  public static IDatabaseService CreateService(string dbType, string connectionString){// 添加参数验证if (string.IsNullOrWhiteSpace(dbType))throw new ArgumentException("数据库类型不能为空", nameof(dbType));if (Enum.TryParse<DatabaseType>(dbType, true, out var type)){return CreateService(type, connectionString);}else{throw new ArgumentException($"不支持的数据库类型: {dbType}", nameof(dbType));}}

}

public interface IDatabaseService : IDisposable
{
DataTable ExecuteQuery(string sql, params object[] parameters);
int ExecuteNonQuery(string sql, params object[] parameters);
object ExecuteScalar(string sql, params object[] parameters);
}

// Services/DatabaseService.cs
public class DatabaseService : IDatabaseService
{
private readonly DatabaseType _dbType;
private readonly DbContext _context;

  public DatabaseService(DatabaseType dbType, string connectionString){switch (dbType){case DatabaseType.SqlServer:_context = new SqlServerContext(connectionString);//_context = new SqlServerContext();break;case DatabaseType.Oracle:_context = new OracleContext(connectionString);//_context = new OracleContext();break;default:throw new ArgumentException("不支持的数据库类型: " + dbType, "dbType");}// 调试:查看实际使用的提供程序var providerName = _context.Database.Connection.GetType().FullName;Console.WriteLine($"使用的数据库连接类型: {providerName}");}public DataTable ExecuteQuery(string sql, params object[] parameters){var dataTable = new DataTable();using (var command = _context.Database.Connection.CreateCommand()){command.CommandText = sql;AddParameters(command, parameters);if (_context.Database.Connection.State != ConnectionState.Open)_context.Database.Connection.Open();using (var reader = command.ExecuteReader()){dataTable.Load(reader);}}return dataTable;}public int ExecuteNonQuery(string sql, params object[] parameters){using (var command = _context.Database.Connection.CreateCommand()){command.CommandText = sql;AddParameters(command, parameters);if (_context.Database.Connection.State != ConnectionState.Open)_context.Database.Connection.Open();return command.ExecuteNonQuery();}}public object ExecuteScalar(string sql, params object[] parameters){using (var command = _context.Database.Connection.CreateCommand()){command.CommandText = sql;AddParameters(command, parameters);if (_context.Database.Connection.State != ConnectionState.Open)_context.Database.Connection.Open();return command.ExecuteScalar();}}private void AddParameters(DbCommand command, object[] parameters){if (parameters == null) return;for (int i = 0; i < parameters.Length; i++){var param = command.CreateParameter();param.ParameterName = GetParameterName(i);param.Value = parameters[i] ?? DBNull.Value;command.Parameters.Add(param);}}private string GetParameterName(int index){switch (_dbType){case DatabaseType.SqlServer: return $"@p{index}";case DatabaseType.Oracle: return $":p{index}";case DatabaseType.Sqlite: return $"@p{index}";default: return $"@p{index}";}}public void Dispose(){_context?.Dispose();}

}

=====================================================
核心方法
public static class EfConnectionHelper
{
private static int _counter = 0;

 public static string CreateNamedConnectionString(string connectionString, string providerInvariantName){var name = $"DynamicConn_{Interlocked.Increment(ref _counter)}";// 1. 动态添加到 ConfigurationManager.ConnectionStringsvar settings = ConfigurationManager.ConnectionStrings;// 💥 关键:通过反射修改只读集合(.NET Framework 允许)var readOnlyField = typeof(ConfigurationElementCollection).GetField("bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);if (readOnlyField != null){readOnlyField.SetValue(settings, false);}settings.Add(new ConnectionStringSettings(name, connectionString, providerInvariantName));return $"name={name}";}

}

=====================================
使用

string connString = "";
using (var db = DatabaseFactory.CreateService(DatabaseType.SqlServer, connString))
{

   var products = db.ExecuteQuery($@"");int count = products.Rows.Count;// 处理数据...

}

string connString_Oracel = "";
using (var db = DatabaseFactory.CreateService(DatabaseType.Oracle, connString_Oracel))
{

   var products = db.ExecuteQuery($@"");int count = products.Rows.Count;// 处理数据...

}

http://www.jsqmd.com/news/53057/

相关文章:

  • 微波烘干设备厂家技术实力与行业应用解析
  • 2025年定期排污扩容器生产商权威推荐榜单:电厂疏水扩容器/定连排疏水扩容器/定期排污疏水扩容器源头厂家精选
  • 2025 年最新推荐激光切管机厂家排行榜:聚焦高效高精度设备,助力企业提升金属管材加工品质高速 / 高精度 / 零尾料 / 免画图 / 全自动 / 三卡盘激光切管机公司推荐
  • 2025 年升降柱机芯厂家最新推荐榜,技术实力与市场口碑深度解析,筛选高性能可靠货源IP68 升降柱机芯 / 防撞升降柱机芯 / 低压升降柱机芯 / 液压升降柱机芯 / 路障机升降柱机芯公司推荐
  • 不只是制药!中药品牌排行榜10强好医生,用石榴谱写产业富民传奇
  • java 上转型对象调用
  • 比较好吸收的奶粉怎么选?这篇文章里有答案
  • PostgreSQL 18 - 时间约束 (Temporal Constraints)
  • 深入解析:Angular【基础语法】
  • 微波烘干设备哪家好?国内优质企业及业务解析
  • U635097 有向图
  • 升级Win11专业工作站版密钥
  • 多线程+asyncio端口扫描器
  • U635735 Treap=Tree+Heap
  • Docker客户端控制局域网服务器 - a-cool
  • 时序约束记录
  • U635732 木叶下
  • U635734 神机
  • 2025深圳粉末冶金展机构权威推荐榜单:2025青岛家博会‌/2025深圳跨境电商展‌/2025新加坡海鲜展源头机构精选
  • U635730 二叉树
  • 2025年宽幅等离子清洗机优质厂家权威推荐榜单:真空等离子清洗机/大气等离子清洗机/等离子体清洗机源头厂家精选
  • 深入解析:简单、高效且低成本的预训练、微调与服务,惠及大众基于 Ray 架构设计的覆盖大语言模型(LLM)完整生命周期的解决方案byzer-llm
  • CF1985G-D-Function
  • 2025 年义乌礼品定制厂家最新推荐榜,聚焦企业生产能力、服务水平与市场认可度多维度解析定制商务礼品 / 公司礼品定制 / 纪念品定制 / 定制伴手礼 / 企业礼品定制 / 客户礼品定制公司推荐
  • U636118 二叉搜索树
  • 2025年口碑好的四川种苗基地排名及采购参考
  • 2025 年义乌商务礼品厂家最新推荐榜,全链条能力与定制服务双维度深度解析商务伴手礼/商务礼品网/定制商务礼品/商务福利礼品/商务实用礼品公司推荐
  • egacy(传统) nftables(较新) 和后端ipvs iptables有关系吗
  • 2025 年透声膜厂家最新推荐榜,技术实力与市场口碑深度解析手机防水/MIC 防水/耳机防水/手表防水/摄像头防水/监控防水/无氟防水/ePTFE 防水透声膜公司推荐
  • KlineCharts对接股票k线数据 股票数据源API