【问题标题】:Connecting to a Database连接到数据库
【发布时间】:2009-11-23 16:24:36
【问题描述】:

这是一个相对简单的问题,但我想确保我这样做是正确的。

连接到数据库的最佳做法是什么?这就是我目前的做法,我想确保这或多或少遵循最佳实践。

private static SQLiteConnection conn;

    public static SQLiteConnection Conn
    {
        get 
        {
            try
            { 
                if (conn == null)
                    conn = new SQLiteConnection(fullName);

                if (conn.State != ConnectionState.Open)
                {
                    conn.ConnectionString = connectionString;
                    conn.Open();
                }
            }
            catch (Exception Excp)
            {
                DataErrorLogger.WriteError(Excp, "");
            }

            return conn;
        }

    }

当我实际使用连接时,我正在这样做。

 using (SQLiteConnection conn = new SQLiteConnection(SQLiteConn.Conn))
        {}

谢谢!

【问题讨论】:

  • 我同意唐的回答,它看起来不错。但请注意,对于 SQLite 以外的数据库 API,上述操作可能不是您想要做的。
  • 谁能解释一下为什么单例实现和使用它的部分都需要“新的 SQLiteConnection”?我不太会读c#,但对我来说看起来很奇怪!
  • @Juergen - 如果这是 ADO.NET 2.0 Provider for SQLite (sourceforge.net/projects/sqlite-dotnet2),它包含一个原型构造函数,用于克隆提供的连接。

标签: c# database sqlite database-connection


【解决方案1】:

在 .NET 中有很多方法可以连接到数据库。你当然已经找到了其中之一,它会正常工作的。

关于 .NET 数据连接,我亲眼目睹并真正体验过三种主要思想流派:

  1. 第一种是一种更“向导”的编码方法,涉及向表单添加连接对象,然后使用表绑定等“向导”将表单提交。这在客户端机器上通常是有效的,因为如果通过绑定和向导功能完成,.NET 会预先优化很多。但是,根据您的操作,它可能会引入更多的网络流量。此外,有时向导不会完全按照您的意愿行事,依赖向导有时可能需要花费数小时的谷歌搜索才能找出向导没有按照您的意愿行事的原因。

  2. 第二种(也是我首选的方式)是编写后端代码来拉取数据集,然后将它们显示在您的软件中。这就是我相信您发布的代码在做什么。我相信它为您提供了数据的最佳灵活性,同时仍然允许您进行一些绑定和魔法编码。这在客户端上通常比选项 1 效率低,因为 DataSets 有时可以通过 byVal 意外传递,并且不能像向导方法那样预先优化。这通常意味着更少的网络流量,因为您的查询将更加隐蔽,并且理论上应该减少调用频率,因为您可以调用数据,存储它,并在其他地方重用它。此外,还有一些关于您可以以这种方式编码的速度的说法。如果您对 SQL 字符串格式等不太了解,我也会发现它会更容易(这可能是我们在办公室为其他一些人使用它的原因)。此外,数据集需要处理,以便从内存中删除。

  3. 我见过的第三种数据连接方法是围绕从 datareader 对象读取数据行而构建的整个类。在对datareaders vs dataConnections and datasets 进行一些研究后,我发现数据读取器方法可以比数据行连接快 10 倍,并且它们使用的内存和资源要少得多。如果您获得了足够的数据或找到了您想要的内容(无论如何都应该使用“TOP”或“WHERE”子句来完成),您还可以选择通过不读取更多行来截断您的结果集。但是,缺点如下:

    • 更难编码,因为您将拥有数据行数组而不是整齐的数据集
    • 大部分情况下无法使用向导(有些仍与数据行数组兼容)
    • 我认为可以肯定地说,大多数初学者都会看到它并说“wtf 发生在这里?”
    • 更多网络流量。
    • 仅限顺序访问。

这些只是我的观察。在选择其中一种方法之前,我会研究任何一种方法。也不要忘记缓存之类的事情,以尽可能地防止往返服务器,但请确保不要缓存在程序运行时会更改的任何内容(来自外部源)。不要忘记多线程和连接池等。对于任何数据访问类,它们都是非常重要的特性。

【讨论】:

    【解决方案2】:

    SQLHelper 当然可以给你一些好主意,但它是专门为 MS Sql Server 编写的,而不是你似乎正在使用的 SqlLite。他们有几十种方法可以做你想做的事,我认为这在很大程度上取决于具体情况。

    1) 考虑多线程。如果你不使用它,那么你可以忽略它,但要确保每个线程都在使用它自己的连接。您可能还想确保一次只有一个线程可以调用您的 SQLiteConnection。每次都返回一个新的 conn,而不是使用类级别的静态 conn。

    2) 使用连接池。这将有助于减少每次调用获取新连接的开销。

    3) 考虑缓存不会更改(或不经常更改)但经常使用的信息。

    4) 尝试捕获一些更具体的异常类型,以便您可以立即采取纠正措施。用户/通行证是否无效?它是安全例外吗?你没有足够的资源吗?

    5) 您应该重新抛出错误,或者根据错误(内部异常)抛出一个新错误,以便调用函数知道它失败了。

    6) 考虑使用一些通用类来帮助您编写上述内容 - 这将使切换引擎或为备用引擎重用代码(Db 类或 IDb 接口)更容易

    7) 你使用的是单例,通常我建议人们避免使用它们,除非他们有充分的理由。我看到很多人滥用它们。

    希望这可以将您带入您想要的正确道路。如果没有,请回来寻求澄清或进一步帮助/。

    【讨论】:

    • Cub,在我的其余代码中,我是否也应该使用 Db 类而不是 SQLite 类?
    • Nathan,我说无论何时何地都要保持通用性。您还可以使用 ProviderFactories 来提供帮助(请参阅 msdn.microsoft.com/en-us/library/dd0w4a2z%28VS.80%29.aspx )。另一种选择是查看 ORM,例如 NHibernate 或 DevExpress 的 XPO ......他们处理 db 的东西,所以你不必。
    【解决方案3】:

    查看 Microsoft 的 SQLHelper 类。它的代码可用于最佳实践数据库访问: http://www.sharpdeveloper.net/source/SqlHelper-Source-Code-cs.html

    它处理所有的连接并且有许多方法来返回不同的数据对象。我们发现它非常有用。

    【讨论】:

      【解决方案4】:

      你应该重新抛出你的错误。否则,当您在代码中随处使用 Conn 时,您将获得 nullReference 异常。否则我觉得没问题。

      【讨论】:

        【解决方案5】:

        1) 使用良好的 ORM。 SQLite 非常受到 NHibernate 和 EntityFramework 的良好支持(它具有第一个生产型非微软实体框架实现)。还有一个项目可以为许多其他支持 SQLite 的数据库创建 LinqToSql 克隆。

        2) 如果您不想使用 ORM。给自己写一个好帮手类。我个人倾向于将我的 sql 存储在嵌入的 xml 资源中,其中包含名称和有关其参数的元数据,然后使用包装类来轻松获取命令。

        注意:

        跨线程共享连接是个坏主意。使用 sqlite 的连接相对便宜,并且有一些 special rules 关于如何跨线程共享它们。

        【讨论】:

          猜你喜欢
          • 2012-10-29
          • 2012-10-23
          • 2011-01-27
          • 2020-02-25
          • 2013-08-05
          • 2014-01-15
          相关资源
          最近更新 更多