当前位置:  开发笔记 > 编程语言 > 正文

将DB Connection对象传递给方法

如何解决《将DBConnection对象传递给方法》经验,为你挑选了3个好方法。

想知道是否建议传递数据库连接对象(到其他模块)或让方法(在另一个模块中)负责设置它.我倾向于让方法设置它,以便在使用之前不必检查连接的状态,只是让调用者将任何所需的数据传递给设置连接所需的调用方法.



1> Marc Gravell..:

我个人喜欢使用严格的连接; 打开它们,使用它们并关闭它们(在"使用"块中,所有都在本地方法中).在大多数情况下,连接池将处理重新使用连接,因此这种方法没有实际开销.

在通过连接的主要优点使用是如此,你可以通过周围的交易; 但是,这TransactionScope是一种在方法之间共享事务的简单方法.

由于这些类是特定于实现的,因此我会编写每个类来打开它自己的本机事务.否则,您可以使用ado.net工厂方法从配置文件(提供程序名称)创建相应的类型.


如果使用TransactionScope在使用不同连接的方法之间共享事务,则事务将成为具有相关开销的分布式事务.因此,在方法之间传递连接(及其事务)仍然更好,同时保持范围紧密.

2> Sam Saffron..:

就个人而言,我喜欢使用SetData和GetData 在Thread Local Storage之上存储我当前打开的连接和事务的堆栈.我定义了一个类来管理我与数据库的连接,并允许它使用dispose模式.这节省了我传递连接和事务的需要,这是我认为使代码混乱和复杂化的东西.

我强烈建议不要在每次需要数据时都要打开连接方法.这将导致一个非常糟糕的情况,即整个应用程序都难以管理事务,并且打开和关闭了太多连接(我知道连接池,从池中查找连接的成本仍然比它更昂贵重用一个对象)

所以我最终得到了这些内容(完全未经测试):

class DatabaseContext : IDisposable {

    List currentContexts;
    SqlConnection connection;
    bool first = false; 

    DatabaseContext (List contexts)
    {
        currentContexts = contexts;
        if (contexts.Count == 0)
        {
            connection = new SqlConnection(); // fill in info 
            connection.Open();
            first = true;
        }
        else
        {
            connection = contexts.First().connection;
        }

        contexts.Add(this);
    }

   static List DatabaseContexts {
        get
        {
            var contexts = CallContext.GetData("contexts") as List;
            if (contexts == null)
            {
                contexts = new List();
                CallContext.SetData("contexts", contexts);
            }
            return contexts;
        }
    }

    public static DatabaseContext GetOpenConnection() 
    {
        return new DatabaseContext(DatabaseContexts);
    }


    public SqlCommand CreateCommand(string sql)
    {
        var cmd = new SqlCommand(sql);
        cmd.Connection = connection;
        return cmd;
    }

    public void Dispose()
    {
        if (first)
        {
            connection.Close();
        }
        currentContexts.Remove(this);
    }
}



void Test()
{
    // connection is opened here
    using (var ctx = DatabaseContext.GetOpenConnection())
    {
        using (var cmd = ctx.CreateCommand("select 1"))
        {
            cmd.ExecuteNonQuery(); 
        }

        Test2(); 
    }
    // closed after dispose
}

void Test2()
{
    // reuse existing connection 
    using (var ctx = DatabaseContext.GetOpenConnection())
    {
        using (var cmd = ctx.CreateCommand("select 2"))
        {
            cmd.ExecuteNonQuery();
        }
    }
    // leaves connection open
}



3> Micah..:

出于自动化测试的目的,通常更容易将其传入.这称为依赖注入.

当您需要编写测试时,您可以创建一个模拟数据库连接对象并传递它而不是真实的.这样,您的自动化测试将不依赖于每次都需要重新填充数据的实际数据库.

推荐阅读
wangtao
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有