Home > .NET | C# | VB | Visual Studio | 言語 > [C#] TableAdapter にトランザクション機能を実装するクラス

[C#] TableAdapter にトランザクション機能を実装するクラス

TableAdapterにトランザクションを実装
TableAdapterにトランザクションを実装

今は Visual C# 2005 Express Edition にて ADO.NET 2.0 Provider for SQLiteを利用してクライアントアプリの開発しています。

TableAdapterにてINSERTやupdateするとどうも更新が遅いので、Googleで調べたら

> http://journal.mycom.co.jp/special/2004/php5/007.html
> SQLiteでは明示的にトランザクションを開始しない限り、INSERT処理の前後に必ず”BEGIN”、”COMMIT”が実行される。

とのことでした。

で、色々試行錯誤して下記のVB記事を参考にC#&SQLite用のトランザクションの処理を追加。

TableAdapterにトランザクションを実装 / うなまな Blog
http://www.ailight.jp/blog/unaap/archive/2007/02/13/13566.aspx

ソースは次のとおりです。

とりあえず貼り付けて起きます、何か問題あったら連絡ください。

TableAdapterにトランザクション機能を実装するクラス
TableAdapterTransactor.cs

using System;
using System.Collections.Generic;
using System.Text;

using System.Data;
using System.Data.SQLite;
using System.Reflection;

/// <summary>
/// TableAdapterにトランザクション機能を実装するクラス
/// </summary>
/// <remarks>
/// 利用方法の例
///     TableAdapterTransactor tat = new TableAdapterTransactor();
///     Data1TableAdapter taData1 = new Data1TableAdapter();
///     Data2TableAdapter taData2 = new Data2TableAdapter();
///
///     tat.AddTableAdapter(taData1);
///     tat.AddTableAdapter(taData2);
///     tat.BeginTransaction();
///     try {
///         taData1.Insert…();
///         taData2.Insert…();
///         tat.Commit();
///     }
///     catch (Exception ex) {
///         tat.Rollback();
///     }
///
/// http://www.ailight.jp/blog/unaap/archive/2007/02/13/13566.aspx
/// </remarks>
class TableAdapterTransactor
{
    private SQLiteConnection _conn = null;
    private SQLiteTransaction _trans = null;
    private List

    _tableAdapters = new List();    #region "Pプロシージャ - GetConnection                     [TableAdapterのConnectionを取得する]"

    /// <summary>
    /// TableAdapterのConnectionを取得する
    /// </summary>
    ///

    TableAdapter     /// <returns>取得したConnection</returns>
    /// <remarks></remarks>
    private SQLiteConnection GetConnection(object tableAdapter)
    {
        Type type = tableAdapter.GetType();
        PropertyInfo connectionProperty = type.GetProperty("Connection", BindingFlags.NonPublic | BindingFlags.Instance);
        SQLiteConnection connection = (SQLiteConnection)connectionProperty.GetValue(tableAdapter, null);
        return connection;
    }
    #endregion    #region "Pプロシージャ - SetConnection                     [TableAdapterのConnectionを設定する]"

    /// <summary>
    /// TableAdapterのConnectionを設定する
    /// </summary>
    ///

    TableAdapter     /// Connection     /// <remarks></remarks>
    private void SetConnection(object tableAdapter, SQLiteConnection connection)
    {
        Type type = tableAdapter.GetType();
        PropertyInfo connectionProperty = type.GetProperty("Connection", BindingFlags.NonPublic | BindingFlags.Instance);
        connectionProperty.SetValue(tableAdapter, connection, null);
    }
    #endregion    #region "Pプロシージャ - GetAdapter                        [TableAdapterのDataAdapterを取得する]"

    /// <summary>
    /// TableAdapterのDataAdapterを取得する
    /// </summary>
    ///

    TableAdapter     /// <returns>取得したDataAdapter</returns>
    /// <remarks></remarks>
    private SQLiteDataAdapter GetAdapter(object tableAdapter)
    {
        Type type = tableAdapter.GetType();
        FieldInfo adapterField = type.GetField("_adapter", BindingFlags.NonPublic | BindingFlags.Instance);
        SQLiteDataAdapter adapter = (SQLiteDataAdapter)adapterField.GetValue(tableAdapter);
        return adapter;
    }
    #endregion

    #region "Pプロシージャ - SetAdapter                        [TableAdapterのDataAdapterを設定する]"
    /// <summary>
    /// TableAdapterのDataAdapterを設定する
    /// </summary>
    /// TableAdapter     /// DataAdapter     /// <remarks></remarks>
    private void SetAdapter(object tableAdapter, SQLiteDataAdapter adapter)
    {
        Type type = tableAdapter.GetType();
        FieldInfo adapterField = type.GetField("_adapter", BindingFlags.NonPublic | BindingFlags.Instance);
        adapterField.SetValue(tableAdapter, adapter);
    }
    #endregion

    #region "Pプロシージャ - InitAdapter                       [TableAdapterのInitAdapterメソッドを呼び出す]"
    /// <summary>
    /// TableAdapterのInitAdapterメソッドを呼び出す
    /// </summary>
    /// TableAdapter     /// <remarks>利用しない</remarks>
    private void InitAdapter(object tableAdapter)
    {
        Type type = tableAdapter.GetType();
        MethodInfo mi = type.GetMethod("InitAdapter", BindingFlags.NonPublic | BindingFlags.Instance);
        mi.Invoke(tableAdapter, null);
    }
    #endregion

    #region "Pプロシージャ - InitCommandCollection             [TableAdapterのInitCommandCollectionメソッドを呼び出す]"
    /// <summary>
    /// TableAdapterのInitCommandCollectionメソッドを呼び出す
    /// </summary>
    /// TableAdapter     /// <remarks>利用しない</remarks>
    private void InitCommandCollection(object tableAdapter)
    {
        Type type = tableAdapter.GetType();
        MethodInfo mi = type.GetMethod("InitCommandCollection", BindingFlags.NonPublic | BindingFlags.Instance);
        mi.Invoke(tableAdapter, null);
    }
    #endregion

    #region "Pプロシージャ - SetTransactionCommands            [TableAdapterのCommandCollectionのTransactionを設定する]"
    /// <summary>
    /// TableAdapterのCommandCollectionのTransactionを設定する
    /// </summary>
    /// TableAdapter     /// Transaction     /// <remarks></remarks>
    private void SetTransactionCommands(object tableAdapter, SQLiteTransaction transaction)
    {
        Type type = tableAdapter.GetType();
        PropertyInfo commandsProperty = type.GetProperty("CommandCollection", BindingFlags.NonPublic | BindingFlags.Instance);
        SQLiteCommand[] commands = (SQLiteCommand[])commandsProperty.GetValue(tableAdapter, null);
        foreach (SQLiteCommand command in commands)
        {
            command.Transaction = transaction;
        }
        this.SetConnection(tableAdapter, transaction.Connection);
    }
    #endregion

    #region "Pプロシージャ - SetTransactionAdapter             [TableAdapterのDataAdapterのTransactionを設定する]"
    /// <summary>
    /// TableAdapterのDataAdapterのTransactionを設定する
    /// </summary>
    /// TableAdapter     /// Transaction     /// <remarks></remarks>
    private void SetTransactionAdapter(object tableAdapter, SQLiteTransaction transaction)
    {
        SQLiteDataAdapter adp = this.GetAdapter(tableAdapter);
        if (adp.InsertCommand != null)
        {
            adp.InsertCommand.Transaction = transaction;
        }
        if (adp.DeleteCommand != null)
        {
            adp.DeleteCommand.Transaction = transaction;
        }
        if (adp.UpdateCommand != null)
        {
            adp.UpdateCommand.Transaction = transaction;
        }
        this.SetAdapter(tableAdapter, adp);
        //this.InitCommandCollection(tableAdapter)
    }
    #endregion

    #region "メソッド - AddTableAdapter                        [TableAdapterを追加する]"
    /// <summary>
    /// TableAdapterを追加する
    /// </summary>
    /// TableAdapter     /// <remarks></remarks>
    public void AddTableAdapter(object tableAdapter)
    {
        this._tableAdapters.Add(tableAdapter);
    }
    #endregion

    #region "メソッド - BeginTransaction                       [トランザクションを開始する]"
    /// <summary>
    /// トランザクションを開始する
    /// </summary>
    /// <remarks>開始する前に、AddTableAdapterメソッドで対象となるTableAdapterを追加すること</remarks>
    public void BeginTransaction()
    {
        int counter = 0;
        foreach (object adapter in this._tableAdapters)
        {
            counter += 1;
            if (counter == 1)
            {
                this._conn = this.GetConnection(adapter);
                if (this._conn.State != ConnectionState.Open)
                {
                    this._conn.Open();
                }
                this._trans = this._conn.BeginTransaction();
            }
            this.SetConnection(adapter, this._conn);
            this.SetTransactionAdapter(adapter, this._trans);
            this.SetTransactionCommands(adapter, this._trans);
        }
    }

    /// <summary>
    /// トランザクションを開始する
    /// </summary>
    /// コネクション     /// <remarks></remarks>
    public void BeginTransaction(SQLiteConnection conn)
    {
        this._conn = conn;
        if (this._conn.State != ConnectionState.Open)
        {
            this._conn.Open();
        }
        this._trans = this._conn.BeginTransaction();
        foreach (object adapter in this._tableAdapters)
        {
            this.SetConnection(adapter, this._conn);
            this.SetTransactionAdapter(adapter, this._trans);
            this.SetTransactionCommands(adapter, this._trans);
        }
    }

    /// <summary>
    /// トランザクションを開始する
    /// </summary>
    /// トランザクション     /// <remarks></remarks>
    public void BeginTransaction(SQLiteTransaction trans)
    {
        this._conn = trans.Connection;
        this._trans = trans;
        foreach (object adapter in this._tableAdapters)
        {
            this.SetConnection(adapter, this._conn);
            this.SetTransactionAdapter(adapter, this._trans);
            this.SetTransactionCommands(adapter, this._trans);
        }
    }
    #endregion

    #region "メソッド - Commit                                 [トランザクションをコミットする]"
    /// <summary>
    /// トランザクションをコミットする
    /// </summary>
    /// <remarks></remarks>
    public void Commit()
    {
        try
        {
            this._trans.Commit();
        }
        catch (Exception ex)
        {
            this._trans.Rollback();
            throw ex;
        }
        finally
        {
            if ((this._conn.State == ConnectionState.Open))
            {
                this._conn.Close();
            }
        }
    }
    #endregion

    #region "メソッド - Rollback                               [トランザクションをロールバックする]"
    /// <summary>
    /// トランザクションをロールバックする
    /// </summary>
    /// <remarks></remarks>
    public void Rollback()
    {
        this._trans.Rollback();
        if ((this._conn.State == ConnectionState.Open))
            {
                this._conn.Close();
            }
        }
        #endregion
    }
}
//eof
 


はずかしながら↓
ttp://bbs.wankuma.com/index.cgi?mode=al2&namber=4858


※ 2008/12/5 ソースコードのインデントが崩れていたので修正しました。

Comments:0

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://blog.kaburk.com/lang/tableadaptertransactor.html/trackback
Listed below are links to weblogs that reference
[C#] TableAdapter にトランザクション機能を実装するクラス from [ま]技術雑記

Home > .NET | C# | VB | Visual Studio | 言語 > [C#] TableAdapter にトランザクション機能を実装するクラス

Translator
MicroAd
あわせて読みたい
あわせて読みたいブログパーツ
なかのひと
ドリコム ジョブボード
edita.jp
メタ情報
いろいろ。
AddClips

Return to page top