为什么我在SQL Server中收到此数据库连接错误?

时间:2009-04-04 02:17:25

标签: c# sql-server

我是数据库编程的初学者,无法连接到我的数据库。我使用以下代码进行连接。

public class dbOpnClse
{
    SqlConnection con = new SqlConnection();
    public SqlConnection openConnection()
    {
        con.ConnectionString ="server=SERVERNAME;database=Test;uid=###;pwd=#####";
        con.Open();
        return con;
    }
    public void closeConnection()
    {
        con.Close();
    }
}

问题是我收到异常“不允许更改'ConnectionString'属性。连接的当前状态是打开的。”此连接代码中是否有任何错误?请帮忙!我正在使用C#.net 2005和SQL Server 2000

5 个答案:

答案 0 :(得分:8)

我最好的猜测是,第二次调用openConnection时还没有关闭它,所以你尝试设置已打开连接的connectionstring属性。这是不允许的。

相反,在.Net中,您希望您的openConnection()样式方法在每次调用时都按照工厂模式的方式实际创建新连接,以便可以正确处理连接。更像是这样:

private SqlConnection CreateConnection()
{
    //even better if the connection string is pulled from a config file
    var result = new SqlConnection("Your connection string here");
    result.Open();
    return result;
}

没有相应的“关闭”方法。相反,我们将依赖IDisposable模式来确保连接始终正确关闭。然后,您将在以下方法中使用该函数和连接:

public DataTable GetRecords(int SomeValue)
{
    var result = new DataTable();

    string sql = "SELECT * FROM [MyTable] WHERE [SomeIntColumn]= @SomeValue";

    using (var cn = CreateConnection() )
    using (var cmd = new SqlCommand(sql, cn) )   
    {
        cmd.Parameters.Add("@SomeValue", SqlDbType.Int).Value =  SomeValue;

        using (var rdr = cmd.ExecuteReader() )
        {
           result.Load(rdr);
        }
    }
    return result;  
}

using语句适用于实现IDisposable接口的任何对象,并且即使抛出异常,它们也可以保证您的连接已关闭。

另请注意,我将CreateConnection()方法设为私有。这是因为这个类将成为您的数据访问层。通过将连接设为私有,您将强制执行一个良好的数据库层,其中与数据库通信的唯一方法是通过此类。 需要与数据库通信的任何代码都应该放在这里。如果此类开始变得太大,您可以将此方法标记为internal而不是私有,并将数据访问层移动到它自己的程序集(Visual Studio中的单独项目)中。关键是现在限制您的方法接受参数的强类型输入。不要尝试构建一个允许直接传入sql的泛型方法。那种方式就是疯狂。

最后,永远不会通过sa帐户从您的应用程序连接到数据库,并将您的帐户详细信息发布到公共网站上并不是那么光明。

答案 1 :(得分:1)

binU中,

您的代码中存在各种问题。首先,您不应该在代码中嵌入连接字符串 - 您应该从Config文件中提取它,以便在部署时可以更改它。其次,不要使用sa帐户登录到您的数据库!! 请不要这样做 - 请相信我这个。

第三,我强烈建议您使用IDisposable接口和Using块来确保您的连接始终关闭。实际上,您依赖于消费代码来调用closeConnection。

试试这个示例代码:

public class MyConnClass : IDisposable
{
    public static string ConnectionString { get; set; }
    protected SqlConnection conn;

    public MyConnClass()
    {
        conn = new SqlConnection(ConnectionString);
        conn.Open();
    }

    public void Dispose()
    {
        conn.Close();
    }
 }

在初始化代码中(例如Web应用程序中的Global.asax.cs)设置静态连接字符串,如下所示:

    MyConnClass.ConnectionString = ConnectionString;

在您的消费类中,您将使用以下内容:

using (MyConnClass myConn = new MyConnClass())
{

    // Database code

}

更新:我建议您考虑的另一件事是修改上面的代码,使其形成数据访问层(DAL)的基础而不仅仅是Connection。也就是说,也将SQL命令对象放在那里并创建代码以简化整体数据访问策略。也就是说,将 Connection 放在一个单独的类中是有点无用的,因为正如Joel所指出的,SqlConnection对象本身就是Disposable。完整的DAL的优势在于它可以从根本上简化您的数据访问。例如,我的DAL让我写下像:

using (MyQueryClass myQuery = new MyQueryClass())
{
   myQuery.Command("Update...").ParamVal("@P1", 1).ParamVal("@P2", 2).Execute();
   return myQuery.Command("Select ...").ParamVal("@Param", SomeVal).ReturnList<SomeType>();
}

你不会最终得到我所做的课程,但希望你能看到一些东西:连接字符串在我的代码中永远不是问题(它是封装的),我可以运行多个命令而不需要所有的设置通常需要拆除,整体语法更流畅。

答案 2 :(得分:0)

据推测,您正试图在代码中的其他位置执行此操作(即更改“ConnectionString”属性)。

最佳做法是在使用连接完成代码块后再打开连接并再次关闭它们(使用using语句),并让连接池处理连接。

答案 3 :(得分:0)

    namespace databaseOp 
{ 
public class dbOpnClse 
{ 
SqlConnection con; 

public SqlConnection openConnection() 
{ 
    //Try this...
    con = new SqlConnection("server=CHEMPAKASSERIL;database=Test;uid=sa;pwd=jeevan");

    //Not this...
    //con.ConnectionString ="server=CHEMPAKASSERIL;database=Test;uid=sa;pwd=jeevan"; 
    con.Open(); 
    return con; 
} 

public void closeConnection() 
{ 
    con.Close(); 
}

    }

}

答案 4 :(得分:0)

您收到此错误,因为您的某些代码在连接已打开时第二次调用openConnection。

您应该阅读this article on ADO.NET best practices