2009-11-23 100 views
2

这是一个相对简单的问题,但我想确保我正确地做到这一点。连接到数据库

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

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)) 
     {} 

谢谢!

+0

我同意唐的回答,它看起来很好。但是,请注意,除了SQLite以外的数据库API,上面可能不是你想要做的。 – 2009-11-23 16:36:53

+1

任何人都可以解释为什么单例实现和使用它的部分都需要“新的SQLiteConnection”?我无法很好地阅读C#,但对我来说这看起来很奇怪! – Juergen 2009-11-23 16:38:27

+0

@Juergen - 如果这是SQLite的ADO.NET 2.0提供程序(http://sourceforge.net/projects/sqlite-dotnet2/),它包含一个克隆提供的连接的原型构造函数。 – 2009-11-23 17:25:53

回答

4

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

有三个主要的思想流派,我已经见过第一手,真正经历过。NET的数据连接:

  1. 第一种是更“wizardy”的方式来编码,其涉及添加连接对象到表单,然后使用表绑定和这样为“向导”您的形式屈服。这在客户端机器上通常是有效的,因为如果.NET通过绑定和向导功能完成的话,.NET会预先优化它。然而,根据你在做什么,它可能会引入更多的网络流量。此外,有时候这些向导不会完全按照你想要的来执行,而依靠向导有时会引入数个小时的谷歌搜索来弄清楚为什么这个向导没有做到你想做的。

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

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

    • 更难代码,因为你将有数据行的阵列,而不是整齐的数据集
    • 无法使用大部分奇才(有些还带有数据行阵列兼容)
    • 我认为可以肯定地说,大多数开始的编码者会看到它并说“wtf发生在这里?”
    • 更多网络流量。
    • 仅限连续访问。

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

3

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

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

+0

不确定这是否适用于SQLite API包装。 – 2009-11-23 16:34:44

3

你应该重新抛出你的错误。否则,当你在你的代码中使用Conn时,你会得到nullReference异常。否则,看起来对我好。

4

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

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

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

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

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

5)您应该重新抛出错误,或根据错误(innerexception)抛出一个新错误,以便调用函数知道错误。

6)考虑使用一些通用类来帮你写上文这将使它更容易交换引擎或再使用一个备用引擎的代码(DB类或接口IDB)

7)你正在使用一个单身人士,一般我建议人们避免他们,除非他们有一个很好的理由。我看到很多误用他们。

希望这可以将你带到你想要的正确道路上。如果不是,请回来并要求澄清或进一步帮助/。

+0

Cub,在我的代码的其余部分中,我应该使用Db Classes而不是SQLite Classes? – Nathan 2009-11-23 16:50:30

+0

Nathan, 我说随时随地保持通用。您还可以使用ProviderFactories来提供帮助(请参阅http://msdn.microsoft.com/en-us/library/dd0w4a2z%28VS.80%29.aspx)。 另一种选择是查看ORM的,如NHibernate或DevExpress的XPO ......他们处理数据库的东西,所以你不必。 – Cub 2009-11-23 17:00:57

2

1)使用好的ORM。 SQLite很好地支持 NHibernate和EntityFramework(它有第一个生产非微软实体框架实现)。还有一个项目可以为许多其他支持SQLite的dbs创建LinqToSql克隆。

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

注:

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