【问题标题】:the perfect way to connect to database?连接数据库的完美方式?
【发布时间】:2011-02-23 13:59:28
【问题描述】:
public class SqlHelper
{
public SqlHelper()
{
}
public static SqlConnection GetConnection()
{
    SqlConnection conn = new SqlConnection();
    conn.ConnectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=" +     System.Web.HttpContext.Current.Server.MapPath(@"~\App_Data\learn.mdf") + ";Integrated Security=True;User Instance=True";
    return conn;
}
public static SqlDataReader ExecuteReader(string sql)
{
    SqlConnection con = GetConnection();
    con.Open();
    SqlCommand cmd = new SqlCommand(sql, con);
    SqlDataReader dr = null;
    try
    {
        dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
    }
    catch
    {
        con.Close();
        return null;
    }
    return dr;
}
public static Object ExecuteScalar(string sql)
{
    SqlConnection con = GetConnection();
    con.Open();
    SqlCommand cmd = new SqlCommand(sql, con);
    Object val = null;
    try
    {
        val = cmd.ExecuteScalar();
    }
    catch
    {
        con.Close();
        return null;
    }
    finally
    {
        con.Close();
    }
    return val;

}
public static DataSet ExecuteDataSet(string sql)
{
    SqlConnection con = GetConnection();
    SqlCommand cmd = new SqlCommand(sql, con);
    DataSet ds = new DataSet();
    SqlDataAdapter adapt = new SqlDataAdapter(cmd);
    try
    {
        adapt.Fill(ds);
    }
    catch
    {
        con.Close();
    }
    return ds;
}
public static void ExecuteNonQuery(string sql)
{
    SqlConnection con = GetConnection();
    con.Open();
    SqlCommand cmd = new SqlCommand(sql, con);
    try
    {
        cmd.ExecuteNonQuery();
    }
    finally
    {
        con.Close();
    }
}
}

这是我用来实现对我的数据库的每次访问的类。但我认为我与数据库连接的方式有点夸大其词,因为每次需要某些东西时我都必须点击 Connect 函数。以及其他用户也会这样做,这会影响性能。
那么,什么是与数据库连接的完美方式——如果这样更好,则保持连接。请注意,我在许多页面中使用数据库!
谢谢

【问题讨论】:

    标签: c# sql-server connection


    【解决方案1】:

    首先,您应该使用“使用”语句来确保在发生故障时正确处理所有 ADO.NET 对象:

    public static void ExecuteNonQuery(string sql) 
    {     
        using(var con = GetConnection())
        {
            con.Open();     
            using(var cmd = new SqlCommand(sql, con))
            {         
                cmd.ExecuteNonQuery();     
            }     
        }
    }
    

    不过,话虽如此,我并不认为这种方法有问题。优点是每次执行一点 SQL 时,连接、命令、适配器和诸如此类的东西都会被正确处理。如果您要创建单个静态 SqlConnection 实例,则会增加连接已在使用中的可能性(例如,当迭代 SqlDataReader 的内容时)。

    如果你真的很在意,提供将连接作为额外参数的重载:

    public static void ExecuteNonQuery(string sql, SqlConnection connection) 
    {     
        using(var cmd = new SqlCommand(sql, con))
        {         
            cmd.ExecuteNonQuery();     
        }     
    }
    

    这样,调用者既可以执行一些不需要多次调用的 SQL,也可以调用您的 GetConnectionMethod 来获取连接,并将其传递给多个调用。

    【讨论】:

    • 非常感谢。看起来很完美:)
    • 在我的代码中,函数 ExecuteReader 在不关闭连接的情况下返回 dr 变量,因此我们可以使用 Datareader 从数据库中读取,当然我不能使用 USING 因为它也会关闭连接,应该我对此做点什么!?!
    • @Rawhi:是的,你可以。当您调用 ExecuteReader 时,请使用其重载之一:command.ExecuteReader(CommandBehavior.CloseConnection)。当阅读器被销毁时,连接将自动关闭。
    • @Rawhi:是的。 SqlDataReader.Close 是 SqlDataReader 实现 IDisposable 的方式。
    【解决方案2】:

    如果这用于网站,那么您必须考虑在页面请求之间,即使来自同一个浏览器,您的服务器状态也会被破坏(一般而言),因此尝试维护页面之间的 SQL 连接。这是第一件事。

    如果每个页面都是单个数据库连接的结果,那么您可能已经按照您真正需要的方式进行了优化,如果您在生成页面时要建立多个连接,那么您可能需要考虑保持连接处于活动状态直到您完成检索数据;通过维护连接或优化您的数据检索来限制您的应用程序和数据库之间的来回。

    【讨论】:

      【解决方案3】:

      维护数据库连接是连接池的工作,而不是连接使用者。最佳做法是尽可能晚地获取连接并尽快释放它。

      using(var connection = new SqlConnection(YourConnectionStringHelperFunction())
      {
      
      }
      

      【讨论】:

      • 我不认为 OP 的类是试图替换连接池管理器。相反,它允许简化 SQL 语句的执行,(理论上)保证根据需要自动实例化和清理对象。他所缺少的只是 using 语句和一种重用现有 SqlConnection 的方法(如果他已经有的话)。
      【解决方案4】:

      您可能需要考虑的一件事是依赖注入模式和一些 IoC 控制器。如果每个页面都需要此连接,则将其设为可注入属性(构造函数可能无法工作,除非您实现某种基础设施类,如 Request)使用一些容器(Unity、Castle、StructureMap)打包所需的东西(也许是缓存,也许是一些其他事情)并让容器为你做魔法(魔法我的意思是大量的样板代码)。 卢克

      【讨论】:

        【解决方案5】:

        首先你可以像这样编写一个单独的类:

        Get 获取数据的方法(带有Select 查询)和Set 操作数据的方法(插入、更新、删除)

        using System.Data;
        using System.Data.Odbc;
        using System.Data.SqlClient;  //using this you can replace instead odbc to sql
        
        // Example SqlCommand, SqlDataAdapter
        class DataBaseConnection
        {
            private OdbcConnection conn1 = new OdbcConnection(@"FILEDSN=C:/OTPub/Ot.dsn;" + "Uid=sa;" + "Pwd=otdata@123;"); //"DSN=Ot_DataODBC;" + "Uid=sa;" +  "Pwd=otdata@123;"
        
            //insert,update,delete
            public int SetData(string query)
            {
                try
                {
                    conn1.Open();
                    OdbcCommand command = new OdbcCommand(query, conn1);
                    int rs = command.ExecuteNonQuery();
                    conn1.Close();
                    return rs;
                }
        
                catch (Exception ex)
                {
                    conn1.Close();
                    throw ex;
                }
        
            }
        
            //select
            public System.Data.DataTable GetData(string sql)
            {
                try
                {
        
                    conn1.Open();
                    OdbcDataAdapter adpt = new OdbcDataAdapter(sql, conn1);
                    DataTable dt = new DataTable();
                    adpt.Fill(dt);
                    conn1.Close();
                    return dt;
        
                }
                catch (Exception ex)
                {
                    conn1.Close();
                    throw ex;
        
        
                }
        
        
            }
        
        
        }
        

        在您的表单中,您可以创建该数据库连接类的对象

           DataBaseConnection db = new DataBaseConnection();
        

        现在您可以使用 get set 方法调用 get set,如下所示

        string sqlSpecialHoliyday = "SELECT * FROM  Holiday WHERE   Date_Time='" + selectdate + "' AND  IDH='50'"; 
                        DataTable dtAdditionalholily = db.GetData(sqlSpecialHoliyday);
        

        AD 你可以使用 Set 方法设置数据

        string insertloginlog = "INSERT INTO Login_Log (Service_No, Machine_Name) VALUES   ('" + serviceID + "','" + machiname + "')";
                        int ret = db.SetData(insertloginlog);
        

        希望这会有所帮助!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-11
          • 2023-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-09
          相关资源
          最近更新 更多