1

最初は Access データベースに接続するアプリケーションを開発しており、近い将来に MS SQL または SQL Express に切り替える予定です。データテーブル構造は両方のタイプのデータベースで同じであり、コードの重複を避け、コードを最小限に抑える方法を見つけようとしています。

たとえば、Access データベースからデータを取得するための次の関数を作成しました。

public static DataTable GetActiveCalls()
    {
        string select = "SELECT call_id, call_time, msisdn, status FROM call WHERE status = 0 OR status = 1 ORDER by call_id ASC";
        OleDbCommand cmd = new OleDbCommand(select, conn);
        DataTable dt = new DataTable("Active Calls");
        OleDbDataAdapter DA = new OleDbDataAdapter(cmd);
        try
        {
            conn.Open();
            DA.Fill(dt);
        }
        catch (Exception ex)
        {
            string sDummy = ex.ToString();
        }
        finally
        {
            conn.Close();
        }
        return dt;
    }

次のコードは SQL Express データベース用です。

public static DataTable GetActiveCalls()
    {
        string select = "SELECT call_id, call_time, msisdn, status FROM call WHERE status = 0 OR status = 1 ORDER by call_id ASC";
        SqlCommand cmd = new SqlCommand(select, conn);
        DataTable dt = new DataTable("Active Calls");
        SqlDataAdapter DA = new SqlDataAdapter(cmd);
        try
        {
            conn.Open();
            DA.Fill(dt);
        }
        catch (Exception ex)
        {
            string sDummy = ex.ToString();
        }
        finally
        {
            conn.Close();
        }
        return dt;
    }

この 2 つの方法はほとんど同じです。唯一の違いは、SqlCommand/OleDbCommand と SqlDataAdapter/OleDbDataAdapter です。たとえば、引数を取るメソッドもいくつかあります。

public static void AddMessage(string callID, string content)
    {
        string select =
            "INSERT INTO message(key, direction, content, read, write_time) VALUES (@callId, 0, @content, 0, @insertTime)";
        OleDbCommand cmd = new OleDbCommand(select, conn);
        cmd.Parameters.AddWithValue("callId", callID.ToString());
        cmd.Parameters.AddWithValue("content", content);
        cmd.Parameters.AddWithValue("insertTime", DateTime.Now.ToString());
        try
        {
            conn.Open();
            cmd.ExecuteScalar();
        }
        catch (Exception ex)
        {
            string sDummy = ex.ToString();
        }
        finally
        {
            conn.Close();
        }
    }

この場合、SQL クエリ文字列も両方のデータベースで同じですが、cmd のタイプ (SqlCommand/OleDbCommand) に違いがあります。

コードの重複を回避し、特定の問題を最適化する方法について誰かが提案してくれれば、本当に感謝しています。

4

2 に答える 2

1

Enterprise Libraryのデータ アクセス ビットを確認する必要があります。基礎となるデータベース プロバイダーの詳細は抽象化されています。例えば:

string sql = @"UPDATE tblContent 
                        SET Title = @Title, Content = @Content, IsPublic = @IsPublic, ItemOrder = @ItemOrder
                        WHERE ContentItemID = @ContentItemID";

Database db = DatabaseFactory.CreateDatabase();
using(DbCommand cmd = db.GetSqlStringCommand(sql))
{
    db.AddInParameter(cmd, "Title", DbType.String, title);
    db.AddInParameter(cmd, "Content", DbType.String, content);
    db.AddInParameter(cmd, "IsPublic", DbType.Boolean, isPublic);
    db.AddInParameter(cmd, "ItemOrder", DbType.Int32, itemOrder);
    db.AddInParameter(cmd, "ContentItemID", DbType.Int32 , contentItemID);

    db.ExecuteNonQuery(cmd);
}

...また...

string sql = "SELECT MenuText FROM tblMenuItems WHERE MenuItemID = @MenuItemID";

Database db = DatabaseFactory.CreateDatabase();
using(DbCommand cmd = db.GetSqlStringCommand(sql))
{
    db.AddInParameter(cmd, "MenuItemID", DbType.Int32, menuItemID);

    using(IDataReader dr = db.ExecuteReader(cmd))
    {
        while(dr.Read())
        {
            return dr["MenuText"].ToString();
        }
        return null;
    }
}

上記の例はどちらも Access と MS SQL で動作します。Jet と MS SQL の両方と互換性のある SQL ステートメントを使用する場合、問題は発生しません。

Access から MS SQL に切り替える場合は、接続文字列を次のように変更するだけです。

<connectionStrings>
    <add 
         name="ContentManager" 
         connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|Content.mdb;" 
         providerName="System.Data.OleDb"/>
</connectionStrings>

...に...

<connectionStrings>
    <add
        name="ContentManager"
        connectionString="Data Source=your.sql.server;Initial Catalog=content;Persist Security Info=True;User ID=cmuser;Password=password"
        providerName="System.Data.SqlClient" />
</connectionStrings>

これを実現するには、EL ディストリビューションで次の DLL を参照するだけです。

Microsoft.Practices.EnterpriseLibrary.Common.dll
Microsoft.Practices.EnterpriseLibrary.Data.dll

一見の価値あり。

乾杯
ケブ

于 2008-11-02T05:16:28.027 に答える
1

データベースに依存しないインターフェイス IDbDataAdapter および IDbCommand を使用し、ファクトリを使用して具体的なインスタンスを作成できます。ここに例があります。

ただし、アプリケーションが非常に単純でない場合は、 NHibernateなどの ORM ソリューションを使用することをお勧めします。Accessと SQL Server の SQL 言語にはほとんど違いがなく、データ アクセス コードがより複雑になる可能性があるためです。

于 2008-11-01T20:21:23.677 に答える