在静态类(ASP.NET)中存储连接

在静态类(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

因为我使用的是Postgresql,不能使用LINQtoSQL,所以我编写了自己的包装器类

这是学生课堂的一部分:

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")*/; }
   }