- 2007-06-29 (金) 18:53
- .NET | C# | VB | Visual Studio | 言語
今は 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.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 ソースコードのインデントが崩れていたので修正しました。
- Newer: [Linux][Debian] Debian etch にて corega USB-TXCを使う
- Older: [C#] ADO.NET 2.0 Provider for SQLite 1.0.43.0 ではまった…。
Comments:0
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 [ま]技術雑記



































