代码之家  ›  专栏  ›  技术社区  ›  Domenic

我应该在哪里创建dbcommand实例?

  •  1
  • Domenic  · 技术社区  · 15 年前

    我似乎有两个选择:

    1. 让我的课实现 IDisposable . 创造我 DbCommand 实例作为 private readonly 字段,并在构造函数中添加它们使用的参数。每当我想写入数据库时,绑定到这些参数(重用相同的命令实例),设置 Connection Transaction 属性,然后调用 ExecuteNonQuery . 在 Dispose 方法,调用 处置 在每个字段上。
    2. 每次我想写入数据库时, using(var cmd = new DbCommand("...", connection, transaction)) 在调用之前,在命令的使用周围添加参数并每次绑定到它们 执行查询 . 我假设我不需要为每个查询使用一个新命令,只需要为每次打开数据库时使用一个新命令(对吗?).

    这两个看起来都有点不雅,可能是不正确的。

    对于1,我的用户很讨厌我的课程现在是 不可分的 只是因为我用了一些 数据库命令 S(应该是他们不关心的实现细节)。我也有点怀疑 数据库命令 周围的实例可能会无意中锁定数据库或其他什么?

    对于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
    }
    
    3 回复  |  直到 15 年前
        1
  •  2
  •   Sky Sanders    15 年前

    多梅尼克 释放sqlitecommand只需向其活动的读卡器发送信号,以释放其读卡器,并将参数和连接引用设置为空。

    只要正确地释放执行的读卡器并关闭/释放连接,缓存命令不会有资源泄漏的风险。

    因此,重用缓存的命令并简单地为参数赋值是迄今为止最有效的实现。

    准备()是 noop 在sqlitecommand中,这样就没有什么好处了。

        2
  •  2
  •   aef123    15 年前

    没有单一的“正确的方法”来处理数据库对象生命周期。这完全取决于您的应用程序需求。

    我个人的偏好是尽可能简单地保存代码。我倾向于根据需要重新创建命令和参数对象。这使我的函数尽可能独立。它大大简化了我必须做的任何再分解。

    如果您担心重新创建对象会影响性能,那么应该加载一个分析器,看看瓶颈在哪里。在我构建的应用程序中,我发现创建dbcommand对象所花费的时间与执行查询所花费的时间相比是如此的不合理,以至于它并没有真正影响到我的应用程序性能。

        3
  •  0
  •   Rohit    15 年前

    我发现使用sqlserver时,如果使用相同连接的命令,速度会更快。我计划测试不同的连接和事务,但它们似乎更快。

    推荐文章