由于我使用的是Postgresql并且无法使用LINQ to SQL,因此我编写了自己的包装类。
这是学生班的一部分:
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();
}
//....
正如您在每次INSERT,DELETE,UPDATE请求中看到的那样,我正在使用Connect()方法连接到数据库。在我不得不等待10分钟插入500行之前,我没有意识到它是多么愚蠢,因为有500个数据库连接。
所以我决定将Connection属性移动到静态DB类。
public static class DB
{
private static NpgsqlConnection connection = null;
public static NpgsqlConnection Connection
{
get
{
if (connection == null)
{
connection = new NpgsqlConnection(String.Format("Server=localhost;Database=db;Uid=uid;Password=pass;pooling=false"));
connection.Open();
}
return connection;
}
}
public static void Run(string queryString)
{
NpgsqlCommand cmd = new NpgsqlCommand(queryString, connection);
cmd.ExecuteScalar();
cmd.Dispose();
}
}
现在有效!我用Run
DB.Run
方法
但是我想知道它是否适用于网上很多人,不仅仅是我。我不确定静态的东西如何与ASP.NET一起工作,也许它会占用大量的内存?..
答案 0 :(得分:5)
最好不要将连接存储在静态字段中。按需创建连接对象,并让连接池管理您的连接。
答案 1 :(得分:3)
您可以为PostgreSQL启用connection pooling ,让pooler为您管理连接。然后你可以毫无顾虑地使用任何一段代码。即使您发出多个打开/关闭命令,pooler也会优化它们。
这为您提供了更多的灵活性,减少了对自定义管理解决方案的担忧,同时减少了代码和边缘情况。它取决于您正在使用的数据库提供程序。连接字符串中的某些内容如:
合并:正确还是错误。控制 是否使用连接池。 默认= True
如果您需要一个使用Postgres连接池的数据库提供程序,则选项 npgsql:Npgsql is a .Net data provider for Postgresql.
它支持连接池为described in the docs。
答案 2 :(得分:1)
静态类是单例。这里的危险就是他们所提到的。因为他们总是活着,所以他们所引用的一切都不会被垃圾收集。
要查看是否是这种情况,请分析您的Web服务器内存。如果它总是增长而且从不收缩,那么你可能会不断地在一个永远不会被收集的静态类中添加引用。
尽管如此,我只是根据需要创建它,并完全避免所有这些。
修改强>
我的意思是不要担心在数据访问层中共享一个连接对象。如果您使用的提供程序支持连接池,则它将处理对数据库的实际连接。只需在数据访问层中的任何位置根据需要使用和处理连接对象。
using (var connection = new NpgsqlConnection("your connection string"))
{
//your data access stuff.
}
我知道这样的代码相当大,笨重,重复,但这就是ADO.NET。只要您通过创建数据访问库/层在自己的类中隔离这些调用,它就非常易于管理。将ADO.NET对象隐藏在静态类中是危险的,因为您将不可避免地忘记在某处关闭连接或调用Dispose(
)。此外,您还有可能构建一个永远不会收集垃圾的大型对象图。
答案 3 :(得分:0)
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")*/; }
}