У меня, похоже, есть два варианта:
- Заставить мой класс реализовать
IDisposable
. Создайте мои DbCommand
экземпляры как private readonly
поля и в конструкторе добавьте параметры, которые они используют. Всякий раз, когда я хочу записать в базу данных, привязать к этим параметрам (повторно используя те же экземпляры команд), установить свойства Connection
и Transaction
, затем вызвать ExecuteNonQuery
. В методе Dispose
вызовите Dispose
для каждого из этих полей.
- Каждый раз, когда я хочу записать в базу данных, пишите
using(var cmd = new DbCommand("...", connection, transaction))
об использовании команды, добавляйте параметры и привязывайте их также каждый раз перед вызовом ExecuteNonQuery
. Я предполагаю, что мне не нужна новая команда для каждого запроса, просто новая команда для каждого открытия базы данных (верно?).
Оба они кажутся несколько не элегантными и, возможно, неправильными.
Для # 1 меня раздражает, что этот класс теперь IDisposable
только потому, что я использовал несколько DbCommand
s (что должно быть деталью реализации, которая им не нужна). Я также несколько подозреваю, что хранение экземпляра 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
}