首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在asp.net-mvc网页中关闭OdbcConnection的正确模式是什么

在asp.net-mvc网页中关闭OdbcConnection的正确模式是什么
EN

Stack Overflow用户
提问于 2011-11-21 10:43:51
回答 4查看 1.5K关注 0票数 1

我有一个网站,我有一个有OdbcConnection的数据访问类。在构造函数中,我有这样的代码:

代码语言:javascript
复制
    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);
    }

在整个类中,我有以下代码:

代码语言:javascript
复制
    private OdbcQuery GetQuery(string sql)
    {
        return new OdbcQuery(_conn, sql);
    }

我正在尝试找出最好的方法来确保我正确地关闭连接。我应该实现IDisposable吗?我应该在每个查询上打开和关闭连接吗?这里还有其他的最佳实践吗?

编辑:

为了澄清,我的用例是,我正在加载一个网页,但它需要大约10次查询才能获得该页面所需的所有数据。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-11-21 11:18:07

检查是否启用了ODBC connection pooling,并使用using语句为您每次访问数据库创建并打开一个连接对象:

代码语言:javascript
复制
using (var conn = new OdbcConnection(_connString)) {
  conn.Open();

  // do a database command ...
}

(请注意,我更改了设计,将_connString存储在字段中)

这是完成此操作最常用的方法,您无需担心在构造函数中创建连接、将其存储在字段中,甚至实现IDisposable

票数 1
EN

Stack Overflow用户

发布于 2011-11-22 02:53:38

所以我提交了另一个答案,因为我意识到我通常使用企业库进行数据访问,而不是纯粹的.net,这会稍微改变一些事情。首先,DataAccessApplicationBlock (DAAB)负责打开和关闭到数据库的连接,所以我没有这样做,因此我像下面这样使用它。同样,在这种情况下,更简单、更有效的方法是在一个存储的Proc中执行所有SELECT语句,然后逐个读取和解析每个结果集。

示例:

存储的进程

代码语言:javascript
复制
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
END

C#代码:

代码语言:javascript
复制
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
            }
        }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2011-11-21 11:00:18

我认为你绝对应该实现IDisposable并遵循dispose pattern,记住垃圾收集器对IDisposable一无所知。作为最后的手段,你应该有一个终结器,如果需要的话,它会杀死数据库连接,但只要有可能,就会抑制终结器(参见我添加的链接,了解所有可怕的细节)。

至于您是想为每个命令创建一个新的连接,还是在对象的生命周期中保留一个连接,这要主观得多,取决于您的场景、环境和许多其他因素。我建议同时探索这两种方法,看看你的想法。如果这是一个“真正的”数据库,也许可以和DBA谈谈,看看他们怎么想的。

无论采用哪种方式,实现IDisposable都是您的好朋友,因为您可以使用所有.NET开发人员都熟悉的模式来处理漂亮、整洁、定义良好的代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8206717

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档