我似乎有兩個選擇:我應該在哪裏創建我的DbCommand實例?
- 讓我的類實現
IDisposable
。將我的DbCommand
實例創建爲private readonly
字段,並在構造函數中添加它們使用的參數。每當我想寫入數據庫時,綁定到這些參數(重用相同的命令實例),設置Connection
和Transaction
屬性,然後調用ExecuteNonQuery
。在Dispose
方法中,在這些字段的每一個上調用Dispose
。 - 每次我想要寫入數據庫時,請在命令的使用周圍寫入
using(var cmd = new DbCommand("...", connection, transaction))
,然後在調用ExecuteNonQuery
之前每次添加參數並綁定它們。我假設每個查詢都不需要新的命令,每次打開數據庫時都需要一個新的命令(對吧?)。
這兩個都顯得有些不雅,可能不正確。
對於#1,這對我的用戶來說很煩,因爲我已經使用了幾個(這應該是他們不關心的實現細節),所以本課程現在是IDisposable
。我也有點懷疑保持一個DbCommand
實例可能會無意中鎖定數據庫或其他東西?
對於#2,感覺就像我每次要寫入數據庫時都要做很多工作(就.NET對象而言),特別是使用參數添加。我似乎每次都創建一個相同的對象,這只是一種不好的練習。
僅供參考,這裏是我當前的代碼,使用#1:
using System;
using System.Net;
using System.Data.SQLite;
public class Class1 : IDisposable
{
private readonly SQLiteCommand updateCookie = new SQLiteCommand("UPDATE moz_cookies SET value = @value, expiry = @expiry, isSecure = @isSecure, isHttpOnly = @isHttpOnly WHERE name = @name AND host = @host AND path = @path");
public Class1()
{
this.updateCookie.Parameters.AddRange(new[]
{
new SQLiteParameter("@name"),
new SQLiteParameter("@value"),
new SQLiteParameter("@host"),
new SQLiteParameter("@path"),
new SQLiteParameter("@expiry"),
new SQLiteParameter("@isSecure"),
new SQLiteParameter("@isHttpOnly")
});
}
private static void BindDbCommandToMozillaCookie(DbCommand command, Cookie cookie)
{
long expiresSeconds = (long)cookie.Expires.TotalSeconds;
command.Parameters["@name"].Value = cookie.Name;
command.Parameters["@value"].Value = cookie.Value;
command.Parameters["@host"].Value = cookie.Domain;
command.Parameters["@path"].Value = cookie.Path;
command.Parameters["@expiry"].Value = expiresSeconds;
command.Parameters["@isSecure"].Value = cookie.Secure;
command.Parameters["@isHttpOnly"].Value = cookie.HttpOnly;
}
public void WriteCurrentCookiesToMozillaBasedBrowserSqlite(string databaseFilename)
{
using (SQLiteConnection connection = new SQLiteConnection("Data Source=" + databaseFilename))
{
connection.Open();
using (SQLiteTransaction transaction = connection.BeginTransaction())
{
this.updateCookie.Connection = connection;
this.updateCookie.Transaction = transaction;
foreach (Cookie cookie in SomeOtherClass.GetCookieArray())
{
Class1.BindDbCommandToMozillaCookie(this.updateCookie, cookie);
this.updateCookie.ExecuteNonQuery();
}
transaction.Commit();
}
}
}
#region IDisposable implementation
protected virtual void Dispose(bool disposing)
{
if (!this.disposed && disposing)
{
this.updateCookie.Dispose();
}
this.disposed = true;
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
~Class1()
{
this.Dispose(false);
}
private bool disposed;
#endregion
}
所以我不需要'Dispose()'的命令本身,只是連接和事務?所以例如我的示例代碼可以在沒有所有'IDisposable'的情況下工作? – Domenic 2010-04-25 19:48:02
@domenic是的,我會說你的課並不表示需要一次性使用,而且絕對不需要析構函數。你可以刪除所有的IDisposable,因爲你的類基本上是一個命令包裝器。 'WriteCurrentCookiesToMozillaBasedBrowserSqlite'完成你需要做的所有清理工作。您可以重新使用infinitum類的同一個實例。 – 2010-04-25 19:56:27