環境ファイルにセクションを追加し、DB接続処理を行う方法
app.config, web.config新しくセクションを定義し、設定を行う。
DB接続情報を登録する例として、1つのデフォルト接続情報と複数のコレクション型を設定する。
完成イメージの.configファイル
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="dbSource" type="My.DB.Configuration.DbSourceSectionHandler, My.DB"/> </configSections> <dbSource> <defaultDbSource name="defaultSource" provider="Oracle.DataAccess.Client" connectionString="user id=myuser;password=userpassword;data source=mydb"/> <dbSources> <add name="sqlserver" provider="System.Data.SqlClient" connectionString="Data Source=servername;Initial Catalog=mydb;User ID=myuser;Password=userpassword"/> <add name="mysql" provider="MySql.Data.MySqlClient" connectionString="server=servername;user id=myuser;password=userpassword;database=mydb;"/> </dbSources> </dbSource> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/> </startup> </configuration>
- configSectionsに新しいセクションのdbSourceを定義する。対象のHandlerクラスとDLL名を指定
- defaultDbSourceで基本接続DBを決定
- dbSourcesの中に複数の名前付き接続情報を格納する。
DbSourceSectionHandlerを追加
参照に「System.Configuration」を追加する。
System.Configuration.ConfigurationSectionを継承する。
using System.Configuration; /// <summary> /// DB接続情報環境情報セクション /// </summary> public class DbSourceSectionHandler : ConfigurationSection { /// <summary> /// 基本DB接続情報 /// </summary> [ConfigurationProperty("defaultDbSource", IsRequired = true)] public DbSourceItem DefaultDbSource { get { return (DbSourceItem)this["defaultDbSource"]; } } /// <summary> /// 接続先が複数存在する場合の接続情報 /// </summary> [ConfigurationProperty("dbSources", IsDefaultCollection = true, IsRequired = false)] public DbSourceConfigItemCollection DbSources { get { return (DbSourceConfigItemCollection)this["dbSources"]; } } }
deSources用のコレクションクラスを作成する。
ConfigurationElementCollectionの継承が必要
using System.Configuration; public class DbSourceConfigItemCollection : ConfigurationElementCollection { /// <summary> /// すべてのキー名のコレクション /// </summary> public string[] AllKeys { get { return (from o in BaseGetAllKeys() select o.ToString()).ToArray(); } } /// <summary> /// 指定されたキーに対応する要素の情報 /// </summary> /// <param name="name">キー名</param> /// <returns>要素</returns> public new DbSourceItem this[string name] { get { return (DbSourceItem)BaseGet(name); } } /// <summary> /// 新しい ConfigurationElement を作成 /// </summary> /// <returns></returns> protected override ConfigurationElement CreateNewElement() { return new DbSourceItem(); } /// <summary> /// 指定した構成要素の要素キーを取得 /// </summary> /// <param name="element"></param> /// <returns></returns> protected override object GetElementKey(ConfigurationElement element) { DbSourceItem item = element as DbSourceItem; return item.Name; } }
最小単位のDbSourceItemを作成
ConfigurationElementを継承する。
using System.Configuration; /// <summary> /// データベース接続情報 /// </summary> public class DbSourceItem : ConfigurationElement { /// <summary> /// 接続先名 /// </summary> [ConfigurationProperty("name", IsRequired = true)] public string Name { get { return (string)this["name"]; } set { this["name"] = value; } } /// <summary> /// プロバイダ /// </summary> /// <remarks> /// ・Oracle.DataAccess.Client /// ・System.Data.SqlClient /// ・System.Data.OleDb /// ・MySql.Data.MySqlClient /// </remarks> [ConfigurationProperty("provider", IsRequired = true)] public string Provider { get { return (string)this["provider"]; } set { this["provider"] = value; } } /// <summary> /// 接続文字列 /// </summary> [ConfigurationProperty("connectionString", IsRequired = true)] public string ConnectionString { get { return (string)this["connectionString"]; } set { this["connectionString"] = value; } } }
プログラム側でConfigファイルより、情報を取得する方法
using System.Configuration; using my.DB.Configuration; //環境設定ファイル(app.config, web.config)より、sbSourceセクション情報を取得する。 var dbsource = (DbSourceSectionHandler)ConfigurationManager.GetSection("dbSource"); //defaultSourceの取得 DbSourceItem defaultSource = dbsource.DefaultDbSource; //コレクション情報の取得 List<DbSourceItem> _dbSources; foreach (string key in dbsource.DbSources.AllKeys) { if (key == _DefaultDbSourceName) { continue; } _dbSources.Add(dbsource.DbSources[key]); }
環境ファイルの内容から、SqlCommandインスタンスの生成例
using System.Data.Common; DbProviderFactory _factory; _factory = DbProviderFactories.GetFactory(_DbSource.Provider); DbConnection _conn = _factory.CreateConnection(); _conn.ConnectionString = _DbSource.ConnectionString; //SqlCommandインスタンスの生成 DbCommand _cmd = _factory.CreateCommand(); _cmd.Connection = _conn; _cmd.CommandType = CommandType.Text; _cmd.CommandText = "select CLM from TABLE"; using(DbDataAdapter adapter = _factory.CreateDataAdapter()) { DataTable dt = new DataTable(); adapter.SelectCommand = _cmd; adapter.Fill(dt); }
DbProviderFactories.GetFactory(_DbSource.Provider)要のmachine.config設定について
各プロバイダー別のGetFactory処理時、どのクラスを参照にするかをmachine.configに設定する必要がある。
細かくはバージョン、PublicKeyまで指定できるが、省略可能
省略時は実行フォルダーの位置から探索される。
machine.config
<system.data> <DbProviderFactories> <add name="Oracle Data Provider for .NET" invariant="Oracle.DataAccess.Client" description="Oracle Data Provider for .NET" type="Oracle.DataAccess.Client.OracleClientFactory, Oracle.DataAccess" /> <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" /> <add name="Npgsql Data Provider" invariant="Npgsql" description="Data Provider for PostgreSQL" type="Npgsql.NpgsqlFactory, Npgsql" /> </DbProviderFactories> </system.data>
- Oracle.DataAccess.Client : Oracle用
- MySql.Data.MySqlClient : MySql用
- Npgsql : PostgreSql用
- SqlServer,OleDbなどは.NET Framework内部にあるため自動で設定される。
参考資料
https://msdn.microsoft.com/ja-jp/library/system.configuration.configurationproperty.aspx
http://d.hatena.ne.jp/seraphy/20120708
http://codezine.jp/article/detail/1200