将SqlConnection传递给类在dispose之后丢失其连接字符串

时间:2014-11-14 07:43:42

标签: c# .net sql-server

我有以下简单的类定义(Windows控制台应用程序):

预期的样本

using System;

namespace ConsoleApplication1 {

    class Test: IDisposable {
        string Text;

        public Test(string str) {
            Text = str;
        }

        public void print() {
            Console.WriteLine("Text: " + Text);
        }

        public void Dispose() {
            Text = "";
        }
    }

    class Program {
        static void Main(string[] args) {
            string TeXT = "Data Source=localhost;Initial Catalog=master;";

            using (Test test = new Test(TeXT)) {
                test.print();
            }

            using (Test test = new Test(TeXT)) {
                test.print();
            }

            Console.ReadKey();
        }
    }
}

在上面的示例中,我将string传递给IDisposabletest。一旦代码超出范围,它就会被处理掉。正如预期的那样,第一次处理测试后没有触及局部变量TeXT,并且可以像测试类一样访问第二个测试类实例。

现在这是真实的情景让我头疼了好几个小时。

实际结果

using System;
using System.Data;
using System.Data.SqlClient;

namespace ConsoleApplication1 {

    class Test: IDisposable{
        SqlConnection dbConn;

        public Test(SqlConnection connection){
            dbConn = connection;
        }

        public void print(){
            Console.WriteLine("Connection" + dbConn.ConnectionString);
        }

        public void Dispose() {
            dbConn.Dispose();
        }
    }

    class Program {
        static void Main(string[] args) {
            SqlConnection sqlConn = new SqlConnection("Data Source=localhost;Initial Catalog=master;");

            using(Test test = new Test(sqlConn)){
                test.print();
            }

            using(Test test = new Test(sqlConn)){
                test.print();
            }

            Console.ReadKey();
        }
    }
}

与我将SqlConnection传递给test类的第一个实例之前相同。处理完第一个实例后,SqlConnection将丢失连接字符串。这使得它无法用于下一个类实例。

问题 为什么在第二种情况下我丢失了ConnectionString?这是一个错误还是故意的?是否有任何解决方案可以避免这种情况,除了与DB Server建立多个连接?我应该停止处理内部连接实例吗?

注意 SqlCommand-SqlConnection Using Disposing issue没有回答我的问题

2 个答案:

答案 0 :(得分:8)

当您处置SqlConection时,您正在处置Test - 但您正在尝试再次使用它。

最好的方法几乎总是在每次需要时创建一个新的SqlConnection - 并在完成后立即处理它。您已经在做第二部分了,但是您应该为第二部分操作创建一个新的SqlConnection实例。

请注意,意味着必须与服务器建立多个连接 - .NET连接池将处理需要多少实际网络连接。

答案 1 :(得分:0)

  

为什么在第二种情况下我丢失了ConnectionString?

因为你的两个例子很少见。

在第一堂课的Dispose()方法中,您设置了Text = "";。这将改变您的班级所持有的参考,但不会改变Main()或其值的参考。因此TeXT中的Main()仍将保留您的连接字符串。

在第二个示例中,您在同一个实例上调用Dispose() ,即从sqlConn传递的Main()

当您Dispose()某个对象时,这并不意味着您无法调用方法或访问属性。一个类在处理它时究竟做了什么,每种类型都不同。对于SqlConnection,它显然将其ConnectionString属性设置为空字符串,其中包括将连接(如果有)返回到连接池。