我是数据库编程的初学者,无法连接到我的数据库。我使用以下代码进行连接。
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
答案 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。