ハロの外部記憶インターフェイス

そろそろ覚える努力が必要かも…

環境ファイルにセクションを追加し、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>
  1. configSectionsに新しいセクションのdbSourceを定義する。対象のHandlerクラスとDLL名を指定
  2. defaultDbSourceで基本接続DBを決定
  3. 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]);
  }
  1. Oracle.DataAccess.Client : ODP.NETを利用する場合のプロバイダー
  2. System.Data.SqlClient : SQl Serverを利用する場合のプロバイダー
  3. System.Data.OleDb : OleDbを利用する場合のプロバイダー
  4. MySql.Data.MySqlClient : MySql.Data.dllを利用する場合のプロバイダー(動作確認まではやってないがメモ)
  5. Npgsql : Npgsql.dllを利用する場合のプロバイダー(動作確認まではやってないがメモ)

環境ファイルの内容から、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>
  1. Oracle.DataAccess.Client : Oracle
  2. MySql.Data.MySqlClient : MySql
  3. Npgsql : PostgreSql
  4. 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