在静态类(ASP.NET)中存储连接
因为我使用的是Postgresql,不能使用LINQtoSQL,所以我编写了自己的包装器类 这是学生课堂的一部分:在静态类(ASP.NET)中存储连接,asp.net,database,class,static,Asp.net,Database,Class,Static,因为我使用的是Postgresql,不能使用LINQtoSQL,所以我编写了自己的包装器类 这是学生课堂的一部分: public class Student : User { private static NpgsqlConnection connection = null; private const string TABLE_NAME = "students"; public int Id { get; set; } public string First
public class Student : User
{
private static NpgsqlConnection connection = null;
private const string TABLE_NAME = "students";
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Password { get; set; }
/// <summary>
/// Reads data from the data reader and moves it to the Student class.
/// </summary>
private static void ReadFields(Student student, NpgsqlDataReader dr)
{
student.Id = Int32.Parse(dr["id"].ToString());
student.FirstName = dr["first_name"].ToString();
student.LastName = dr["last_name"].ToString();
student.Password = dr["password"].ToString();
}
/// <summary>
/// Updates the student
/// </summary>
public void Update()
{
Connect();
Run(String.Format("UPDATE " + TABLE_NAME + " SET first_name='{0}', last_name='{1}', password='{2}' WHERE id={3}", FirstName, LastName, Password, Id));
connection.Dispose();
}
/// <summary>
/// Inserts a new student
/// </summary>
public void Insert()
{
Connect();
Run(String.Format("INSERT INTO " + TABLE_NAME + " (first_name, last_name, password) VALUES ('{0}', '{1}', '{2}')",FirstName, LastName, Password));
connection.Dispose();
}
private static void Run(string queryString)
{
NpgsqlCommand cmd = new NpgsqlCommand(queryString, connection);
cmd.ExecuteScalar();
cmd.Dispose();
}
private static void Connect()
{
connection = new NpgsqlConnection(String.Format("Server=localhost;Database=db;Uid=uid;Password=pass;pooling=false"));
connection.Open();
}
//....
现在可以了!我将学生类中的所有Run
方法替换为DB.Run
但我想知道它是否能在很多在线用户中正常工作,而不仅仅是我。我不确定ASP.NET如何处理静态内容,可能会占用大量内存。最好不要将连接存储在静态字段中。按需创建连接对象,并让连接池管理您的连接。您可以为PostgreSQL启用,并让池管理器为您管理连接。然后您就可以放心地使用任意一段代码了。即使您发出多个打开/关闭命令,池处理程序也会对其进行优化 这为您提供了更大的灵活性,减少了对自定义管理解决方案的担忧,也减少了代码和边缘案例。它将取决于您使用的数据库提供程序。连接字符串中的某些内容,如: 池:正确或错误。控制 是否使用连接池。 默认值=真
如果您需要为Postgres使用连接池的数据库提供程序,一个选项是:
Npgsql是Postgresql的.Net数据提供程序。
它支持连接池,因为静态类是单例的。这里的危险是他们所指的。因为它们总是活着,所以它们引用的所有内容都不会被垃圾收集
public class Dataconnect
{
public static string connstring = ConfigurationSettings.AppSettings["SQLConnection"].ToString();
SqlConnection objcon = new SqlConnection(connstring);
SqlCommand objcmd = new SqlCommand();
public bool Opencon()
{
try {
if (objcon.State == ConnectionState.Closed)
{
objcon.Open();
}
objcmd.Connection = objcon;
return true;
}
catch (Exception ex) { throw new Exception("Error: In Open connesction"); return false; }
}
public bool Closecon()
{
try
{
if (objcon.State == ConnectionState.Open)
{
objcon.Close();
}
objcmd.Dispose();
return true;
}
catch (Exception ex) { throw new Exception("Error: In Close connesction"); return false; }
}
public static int ExecuteQuery(SqlCommand sqlcmd)
{
try
{
Dataconnect objdc = new Dataconnect();
int affectedrecord = 0;
if (objdc.Opencon() == true)
{
sqlcmd.Connection = objdc.objcon;
affectedrecord = sqlcmd.ExecuteNonQuery();
objdc.Closecon();
objdc = null;
return affectedrecord;
}
else { return affectedrecord; }
}
catch (Exception ex) { throw ex;/* new Exception("Error: In ExecuteNonquery");*/ }
}
public static DataTable Generatedatatable(SqlCommand sqlcmd)
{
try { Dataconnect objdc = new Dataconnect();
if (objdc.Opencon() == true)
{
sqlcmd.Connection = objdc.objcon;
SqlDataReader dr;
DataTable objdt = new DataTable();
dr = sqlcmd.ExecuteReader();
objdt.Load(dr);
objdc.Closecon();
objdc = null;
return objdt;
}
else { return null; }
}
catch (Exception Exception) { throw Exception /*new Exception("Error: In Generatedatatable")*/; }
}
若要查看是否存在这种情况,请配置web服务器内存。如果它总是增长而从不收缩,那么您可能会在一个从未被收集的静态类中不断添加引用
public class Dataconnect
{
public static string connstring = ConfigurationSettings.AppSettings["SQLConnection"].ToString();
SqlConnection objcon = new SqlConnection(connstring);
SqlCommand objcmd = new SqlCommand();
public bool Opencon()
{
try {
if (objcon.State == ConnectionState.Closed)
{
objcon.Open();
}
objcmd.Connection = objcon;
return true;
}
catch (Exception ex) { throw new Exception("Error: In Open connesction"); return false; }
}
public bool Closecon()
{
try
{
if (objcon.State == ConnectionState.Open)
{
objcon.Close();
}
objcmd.Dispose();
return true;
}
catch (Exception ex) { throw new Exception("Error: In Close connesction"); return false; }
}
public static int ExecuteQuery(SqlCommand sqlcmd)
{
try
{
Dataconnect objdc = new Dataconnect();
int affectedrecord = 0;
if (objdc.Opencon() == true)
{
sqlcmd.Connection = objdc.objcon;
affectedrecord = sqlcmd.ExecuteNonQuery();
objdc.Closecon();
objdc = null;
return affectedrecord;
}
else { return affectedrecord; }
}
catch (Exception ex) { throw ex;/* new Exception("Error: In ExecuteNonquery");*/ }
}
public static DataTable Generatedatatable(SqlCommand sqlcmd)
{
try { Dataconnect objdc = new Dataconnect();
if (objdc.Opencon() == true)
{
sqlcmd.Connection = objdc.objcon;
SqlDataReader dr;
DataTable objdt = new DataTable();
dr = sqlcmd.ExecuteReader();
objdt.Load(dr);
objdc.Closecon();
objdc = null;
return objdt;
}
else { return null; }
}
catch (Exception Exception) { throw Exception /*new Exception("Error: In Generatedatatable")*/; }
}
老实说,我只会根据需要创建它,并且完全避免所有这些
编辑:
我的意思是不用担心在数据访问层上共享一个连接对象。如果您使用的提供程序支持连接池,那么它将处理与数据库的实际连接。只需在数据访问层的任何位置根据需要使用和处置连接对象
using (var connection = new NpgsqlConnection("your connection string"))
{
//your data access stuff.
}
我知道这样的代码相当大、庞大且重复,但这是ADO.NET。只要通过创建数据访问库/层,将这些调用隔离在它们自己的类中,就非常容易管理。将ADO.NET对象隐藏在静态类中是危险的,因为您不可避免地会忘记关闭连接或在某个地方调用
Dispose(
)。此外,您还可能构建一个永远不会被垃圾回收的大型对象图。谢谢!汇集资金确实有帮助。所以,现在我可以不用担心打开数百个连接并使用旧的方式,或者我仍然应该做一些优化吗?为什么将连接存储在静态字段中是危险的?首先,它将您限制为单个连接,其中连接池使用尽可能多的连接,以最有效的方式使用您需要的连接(你不必担心).好的,这就是我所想的。我以前在静态类方面已经有过不好的经验…你说的“避免所有这些”是什么意思?避免包装并直接访问SQL?与其只发布一段代码,不如解释一下为什么这段代码解决了所提出的问题。没有解释,这不是答案。
public class Dataconnect
{
public static string connstring = ConfigurationSettings.AppSettings["SQLConnection"].ToString();
SqlConnection objcon = new SqlConnection(connstring);
SqlCommand objcmd = new SqlCommand();
public bool Opencon()
{
try {
if (objcon.State == ConnectionState.Closed)
{
objcon.Open();
}
objcmd.Connection = objcon;
return true;
}
catch (Exception ex) { throw new Exception("Error: In Open connesction"); return false; }
}
public bool Closecon()
{
try
{
if (objcon.State == ConnectionState.Open)
{
objcon.Close();
}
objcmd.Dispose();
return true;
}
catch (Exception ex) { throw new Exception("Error: In Close connesction"); return false; }
}
public static int ExecuteQuery(SqlCommand sqlcmd)
{
try
{
Dataconnect objdc = new Dataconnect();
int affectedrecord = 0;
if (objdc.Opencon() == true)
{
sqlcmd.Connection = objdc.objcon;
affectedrecord = sqlcmd.ExecuteNonQuery();
objdc.Closecon();
objdc = null;
return affectedrecord;
}
else { return affectedrecord; }
}
catch (Exception ex) { throw ex;/* new Exception("Error: In ExecuteNonquery");*/ }
}
public static DataTable Generatedatatable(SqlCommand sqlcmd)
{
try { Dataconnect objdc = new Dataconnect();
if (objdc.Opencon() == true)
{
sqlcmd.Connection = objdc.objcon;
SqlDataReader dr;
DataTable objdt = new DataTable();
dr = sqlcmd.ExecuteReader();
objdt.Load(dr);
objdc.Closecon();
objdc = null;
return objdt;
}
else { return null; }
}
catch (Exception Exception) { throw Exception /*new Exception("Error: In Generatedatatable")*/; }
}