当前位置: 首页 > 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.zskr.cn/news/63030.html

相关文章:

  • 2025 年升降柱机芯厂家最新推荐榜,技术实力与市场口碑深度解析,筛选高性能可靠货源IP68 升降柱机芯 / 防撞升降柱机芯 / 低压升降柱机芯 / 液压升降柱机芯 / 路障机升降柱机芯公司推荐
  • java 上转型对象调用
  • 比较好吸收的奶粉怎么选?这篇文章里有答案
  • 深入解析:Angular【基础语法】
  • U635097 有向图
  • 时序约束记录
  • U635732 木叶下
  • 2025深圳粉末冶金展机构权威推荐榜单:2025青岛家博会‌/2025深圳跨境电商展‌/2025新加坡海鲜展源头机构精选
  • U635730 二叉树
  • 2025年宽幅等离子清洗机优质厂家权威推荐榜单:真空等离子清洗机/大气等离子清洗机/等离子体清洗机源头厂家精选
  • 深入解析:简单、高效且低成本的预训练、微调与服务,惠及大众基于 Ray 架构设计的覆盖大语言模型(LLM)完整生命周期的解决方案byzer-llm
  • 2025 年义乌礼品定制厂家最新推荐榜,聚焦企业生产能力、服务水平与市场认可度多维度解析定制商务礼品 / 公司礼品定制 / 纪念品定制 / 定制伴手礼 / 企业礼品定制 / 客户礼品定制公司推荐
  • U636118 二叉搜索树
  • 2025年口碑好的四川种苗基地排名及采购参考
  • egacy(传统) nftables(较新) 和后端ipvs iptables有关系吗
  • 2025 年透声膜厂家最新推荐榜,技术实力与市场口碑深度解析手机防水/MIC 防水/耳机防水/手表防水/摄像头防水/监控防水/无氟防水/ePTFE 防水透声膜公司推荐
  • KlineCharts对接股票k线数据 股票数据源API
  • 右击转到定义,f12会跳转到错误的方法上
  • 2025年核心年核心方案商遴选指南:企业智能BI私有化部署厂商与AI知识库(含DeepSeek)部署方案商综合解析
  • 2025年工字钢弯管直销厂家权威推荐榜单:圆管弯管‌/铝型材弯管‌/中频热弯管源头厂家精选
  • 留学中介排名TOP10重磅发布,谁是申请服务标杆
  • 推荐几家ins推广公司,五家效果不错的ins营销服务商盘点
  • 2025年11月优质推广获客服务商TOP5推荐:覆盖Facebook、LinkedIn、TikTok、Google、INS等平台
  • 留学中介机构排名TOP10新鲜出炉,这家值得选择
  • 2025年昆明清洁公司避坑榜:口碑认证+清洁达标率98%测评推荐
  • 2025杭州英国留学费用 排名哪家好
  • 2025 年苏州无人机培训基地推荐:翼无忧航空 ——CAAC 认证资质与全链条服务的优质之选caac无人机培训/无人机执照培训/超视距无人机培训/无人机驾驶员培训机构推荐
  • 2025 年义乌保温杯定制厂家源头厂家最新推荐榜,聚焦企业技术实力与市场口碑深度解析公司礼品定制保温杯/广告杯定制/纪念品保温杯定制/商务礼品保温杯/企业定制水杯/专属定制保温杯公司推荐
  • 2025年铁皮文件柜定做实力厂家权威推荐榜单:铁皮柜文件柜‌/办公铁皮文件柜‌/文件柜铁皮柜源头厂家精选
  • [ssh 命令]