2009年10月20日火曜日

[.NET]ADO.NET 2.0 基本クラスおよびファクトリによる汎用的なコーディング

ADO.NET 2.0 基本クラスおよびファクトリによる汎用的なコーディングにしたがって、ファクトリメソッドを使ったDB接続(今回もCSVファイル)をやってみました。

DbProviderFactories.GetFactoryの引数で渡す情報はmachine.configに定義されており、私の環境では、
  • Odbc Data Provider(System.Data.Odbc)
  • OleDb Data Provider(System.Data.OleDb)
  • OracleClient Data Provider(System.Data.OracleClient)
  • SqlClient Data Provider(System.Data.SqlClient)
  • Microsoft SQL Server Compact Data Provider(System.Data.SqlServerCe.3.5)

が定義されていました(括弧内がファクトリに渡す文字列)。コードはこんな感じ。

private void button1_Click(object sender, EventArgs e)
{
    //using System.Data.Common;

    string csvDir = @"d:\temp";
    string csvFileName = "test.csv";

    //接続文字列を組み立てる
    DbProviderFactory f = DbProviderFactories.GetFactory("System.Data.Odbc");
    DbConnectionStringBuilder builder = f.CreateConnectionStringBuilder();
    builder["Driver"] = "Microsoft Text Driver (*.txt; *.csv)";
    builder["dbq"] = csvDir;
    builder["Extension"] = "asc,csv,tab,txt";

    using (IDbConnection con = f.CreateConnection())
    {
        con.ConnectionString = builder.ConnectionString;
        con.Open();

        string strSQL = "SELECT * FROM " + csvFileName + " WHERE idx < 3";
        using (IDbCommand cmd = f.CreateCommand())
        {
            cmd.CommandText = strSQL;
            cmd.Connection = con;
            using (IDataReader rd = cmd.ExecuteReader())
            {
                PrintData(rd);
            }
        }

    }

}

private void PrintData(IDataReader rd)
{
    StringBuilder sb = new StringBuilder();
    //カラム名を取得し、カンマ区切りで編集します
    sb.AppendLine("--------------------------------------");
    for (int cnt = 0; cnt < rd.FieldCount; cnt++)
    {
        sb.Append(rd.GetName(cnt)).Append(",");
    }
    sb.Remove(sb.Length - 11);
    sb.AppendLine("");
    sb.AppendLine("--------------------------------------");

    //データを取得しカンマ区切りで編集します
    for (int row = 0; rd.Read(); row++)
    {
        for (int col = 0; col < rd.FieldCount; col++)
        {
            sb.Append(rd.GetValue(col)).Append(",");
        }
        sb.Remove(sb.Length - 11);
        sb.AppendLine("");
    }
    sb.AppendLine("--------------------------------------");

    System.Diagnostics.Debug.WriteLine(sb.ToString());

}
}


システム的には汎用性が高い。といえそうですが、実際にお客さんの要望として、複数のDBMSに対応した。。。というのは少ないような気がします。フレームワーク的なものであれば別ですが。

まぁとはいえ単体でユニットテストを組む場合などに応用できそうですね。

0 件のコメント: