我似乎有两个选择:
IDisposable
.创建我的DbCommand
实例为 private readonly
字段,并在构造函数中添加它们使用的参数。每当我想写入数据库时,绑定(bind)到这些参数(重用相同的命令实例),设置 Connection
和 Transaction
属性,然后调用 ExecuteNonQuery
.在 Dispose
方法,调用Dispose
在这些领域中的每一个。 using(var cmd = new DbCommand("...", connection, transaction))
围绕命令的使用,每次调用ExecuteNonQuery
之前添加参数并绑定(bind)到它们.我假设我不需要每个查询的新命令,每次打开数据库时都需要一个新命令(对吗?)。 这两者似乎都有些不雅,而且可能不正确。
对于#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
}
最佳答案
多米尼克,
处理 SQLiteCommand 只是简单地向其事件阅读器发出信号以处理其阅读器并将参数和连接引用设置为 null。
只要您正确处置已执行的阅读器并关闭/处置连接,就不会因缓存命令而面临资源泄漏的风险。
因此,重用缓存的命令并简单地为参数分配值是迄今为止最有效的实现。
.Prepare() 是 noop
在 SQLiteCommand 中,所以那里没有任何好处。
关于.net - 我应该在哪里创建我的 DbCommand 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1252039/