我有一个网站,我有一个有OdbcConnection的数据访问类。在构造函数中,我有这样的代码:
public MySybaseProvider()
{
_conn = GetConn();
}
public OdbcConnection GetConn()
{
string connString = "DSN=SybaseIQ;Eng=SYSERVER;Links=tcpip(Host=" + _connectionInfo.Host + ";Port=" + _connectionInfo.Port + ");UID=" + _connectionInfo.User + ";PWD=" + _connectionInfo.Pwd + ";";
return new OdbcConnection(connString);
}在整个类中,我有以下代码:
private OdbcQuery GetQuery(string sql)
{
return new OdbcQuery(_conn, sql);
}我正在尝试找出最好的方法来确保我正确地关闭连接。我应该实现IDisposable吗?我应该在每个查询上打开和关闭连接吗?这里还有其他的最佳实践吗?
编辑:
为了澄清,我的用例是,我正在加载一个网页,但它需要大约10次查询才能获得该页面所需的所有数据。
发布于 2011-11-21 11:18:07
检查是否启用了ODBC connection pooling,并使用using语句为您每次访问数据库创建并打开一个连接对象:
using (var conn = new OdbcConnection(_connString)) {
conn.Open();
// do a database command ...
}(请注意,我更改了设计,将_connString存储在字段中)
这是完成此操作最常用的方法,您无需担心在构造函数中创建连接、将其存储在字段中,甚至实现IDisposable。
发布于 2011-11-22 02:53:38
所以我提交了另一个答案,因为我意识到我通常使用企业库进行数据访问,而不是纯粹的.net,这会稍微改变一些事情。首先,DataAccessApplicationBlock (DAAB)负责打开和关闭到数据库的连接,所以我没有这样做,因此我像下面这样使用它。同样,在这种情况下,更简单、更有效的方法是在一个存储的Proc中执行所有SELECT语句,然后逐个读取和解析每个结果集。
示例:
存储的进程
Create PROCEDURE [dbo].[GetUserByEmail]
@UserID int,
@AccountID int,
AS
BEGIN
SET NOCOUNT OFF;
SELECT * FROM Users WHERE UserID = @UserID and AccountID = @AccountID
SELECT * FROM UserAddresses WHERE UserID = @UserID
ENDC#代码:
public class DataAccessLayer
{
private static DataAccessLayer me = new DataAccessLayer();
private DataAccessLayer() { }
public static DataAccessLayer GetInstance()
{
return me;
}
public Database GetDatabase(string connectionString, string provider)
{
DbProviderFactory providerFactory = DbProviderFactories.GetFactory(provider);
return new GenericDatabase(connectionString,
providerFactory);
}
}
public class Repository
{
protected Database curDatabase;
public Repository()
{
curDatabase = DataAccessLayer.GetInstance().GetDatabase("ConnectionString", "System.Data.Odbc");
}
public Database CurrentDatabase
{
get { return curDatabase; }
}
}
public class UserRepository : Repository
{
public User GetUser(int urserID, int accountID)
{
using (IDataReader dataReader = CurrentDatabase.ExecuteReader("StroedProcName", urserID, accountID))
{
//User Details
while (dataReader.Read())
{
//Parse Data
}
dataReader.NextResult();
//User Address(es)
while (dataReader.Read())
{
//Parse Data
}
}
}
}发布于 2011-11-21 11:00:18
我认为你绝对应该实现IDisposable并遵循dispose pattern,记住垃圾收集器对IDisposable一无所知。作为最后的手段,你应该有一个终结器,如果需要的话,它会杀死数据库连接,但只要有可能,就会抑制终结器(参见我添加的链接,了解所有可怕的细节)。
至于您是想为每个命令创建一个新的连接,还是在对象的生命周期中保留一个连接,这要主观得多,取决于您的场景、环境和许多其他因素。我建议同时探索这两种方法,看看你的想法。如果这是一个“真正的”数据库,也许可以和DBA谈谈,看看他们怎么想的。
无论采用哪种方式,实现IDisposable都是您的好朋友,因为您可以使用所有.NET开发人员都熟悉的模式来处理漂亮、整洁、定义良好的代码。
https://stackoverflow.com/questions/8206717
复制相似问题