我应该在哪里创造我DbCommand实例?
-
12-09-2019 - |
题
我似乎有两种选择:
- 让我的类的实施
IDisposable
.创造我DbCommand
实例private readonly
领域,在构造、添加的参数,他们使用。每当我想到写入数据库,结合这些参数(重复使用相同的命令实例),设置Connection
和Transaction
特性,那么呼叫ExecuteNonQuery
.在Dispose
方法,呼叫Dispose
在每个这些领域。 - 每次我想写的数据库,编写
using(var cmd = new DbCommand("...", connection, transaction))
周围使用的命令,并增加参数结合到它们的每一次作为好了,话之前ExecuteNonQuery
.我想我不需要一个新的命令为每个查询中,只有新命令,对每次我打开的数据库(对吗?).
这两个似乎有点不雅和可能的不正确的。
#1,它是令人讨厌我的用户,我这类是现在 IDisposable
只是因为我使用一些 DbCommand
s(这应该是一个执行情况的细节,他们不关心).我也有点怀疑保留 DbCommand
实例周围可能会不经意地锁定数据库什么的?
#2,感觉就像我做了很多工作(在条件。净的对象)每次我想写的数据库,尤其是与参数的增加。这似乎是我创建同一目的每一时间,这只是感觉不好的做法。
对于参考,这是我目前代码,用#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简单的信号,它的积极读者,处置它的读者,并将参数和连接的参考空。
你是不是在风险的资源泄漏通过高速缓存的命令只要你正确地处置的执行阅读器及关闭/处置的连接。
因此,重复使用缓存的命令,并简单地分配价值观的参数是迄今为止最有效的执行。
.准备()是一个 noop
在SQLiteCommand因此没有好处了。
其他提示
没有单一的"正确的方式"来处理数据库对象的生命周期。这是所有依赖于你的应用程序的需要。
我个人喜好是保留的代码尽可能简单。我倾向于重新命令和参数的对象的需要。这让我能够作为自给自足作为可能。它已大大简化的任何重新解我不得不这样做。
如果你关心的绩效打击的重现对象,你应该载入立了一个探查,看看你的瓶颈。在应用程序,我已经建立,我发现的时间花在创造DbCommand对象是那么无关紧要相比花费的时间执行查询,它并不真正因素对我的应用程序的性能。
我已经找到与sql server如果我们重新使用该命令相同的连接,其速度要快得多。我的计划,以试验对于不同的连接和交易,但他们似乎是更快。
不隶属于 StackOverflow