• CommandBehavior.CloseConnection使用


    
    

    其用在ExecuteReader(c)中,返回对象前不能关闭数据库连接,须用CommandBehavior.CloseConnection;

    
    

    这是一个关于实际知识点的问题,面试官考查的是应聘者数据库访问的编程经验。本节将针对这个问题展开具体的分析。对于此类关于具体知识点的问题,读者在平时应该注意积累,这样在面试中才能从容应答。

    
    

    所涉及的知识点

    
    

    CommandBehavior.CloseConnection的使用

    
    

    分析问题

    
    

    由于流模式读取数据库的特点,在具体应用时很难确定数据库连接何时才能被关闭,因为读取的动作是连续进行的,下面是一个常见的数据访问层的静态方法:



    ///
    <summary> /// 常见的获取SqlDataReader方法 /// 通常的数据访问层都会提供这个方法 /// </summary> static SqlDataReader GetReader() { //通过连接字符串获取连接 SqlConnection con = new SqlConnection(conn_String); try { //打开连接,执行查询 //并且返回SqlDataReader con.Open(); SqlCommand cmd = con.CreateCommand(); cmd.CommandText = Sql; SqlDataReader dr = cmd.ExecuteReader(); return dr; } finally { //这里的代码处于两难的境地 //如果这里执行关闭:con.Close();那返回的 SqlDataReader将毫无用处,因为其 //依赖的连接已经关闭 //如果这里不执行con.Close();那返回后该连接 //将永远无法关闭,因为调用方无法 //得到连接对象 } }

    正如代码注释里描述的那样,这样的方法既不能关闭连接,也不能保持连接打开状态。很多系统为了解决这样两难的境地,只能放弃使用Reader模式的数据源,或者把连接对象交给方法调用者,以便进行关闭。

    而CommandBehavior.CloseConnection的功能恰好就是为了避免类似的尴尬境地,它能够保证当SqlDataReader对象被关闭时,其依赖的连接也会被自动关闭。代码9-2展示了使用CommandBehavior.CloseConnection和不使用CommandBehavior.CloseConnection的区别。

    这里以SqlDataReader为例进行说明,对于其他命名空间下的XXXDataReader对象,其功能是类似的。

    首先为了展示功能,代码9-2包含了两个静态的返回SqlDataReader的方法,其中一个在执行ExecuteReader方法时传入了CommandBehavior.CloseConnection方法class UseCommandBehavior

    
    {
    
    //数据库看连接字符串
    
    const String conn_String = "Server=localhost;Integrated Security=true;database=NetTest";
    
    const String Sql = "select * from dbo.DepartCost";       
    

    /// <summary>
    
    /// 使用CommandBehavior.CloseConnection
    
    /// </summary>
    
    /// <param name="con">为了测试需要,传入连接对象</param>
    
    static SqlDataReader GetReader_CloseConnection(SqlConnection con)
    
    {
    
    try
    
    {
    
    //打开连接,执行查询
    
    //并且返回SqlDataReader
    
    con.Open();
    
    SqlCommand cmd = con.CreateCommand();
    
    cmd.CommandText = Sql;
    
    SqlDataReader dr = cmd.ExecuteReader
    
    (CommandBehavior.CloseConnection);
    
    return dr;
    
    }
    
    finally
    
    {
    
    //因为使用了CommandBehavior.CloseConnection,
    
    //这里不需要关闭连接
    
    //con.Close();
    
    }
    
    }
    /// <summary>
    
    /// 不使用CommandBehavior.CloseConnection
    
    /// </summary>
    
    /// <param name="con">为了测试需要,传入连接对象</param>
    
    static SqlDataReader GetReader_NoCloseConnection(SqlConnection con)
    
    {
    
    try
    
    {
    
    //打开连接,执行查询
    
    //并且返回SqlDataReader
    
    con.Open();
    
    SqlCommand cmd = con.CreateCommand();
    
    cmd.CommandText = Sql;
    
    SqlDataReader dr = cmd.ExecuteReader();
    
    return dr;
    
    }
    
    finally
    
    {
    
    //为了使返回的SqlDataReader可用,这里不能关闭连接
    
    //con.Close();
    
    }
    
    }
    
    }
    
    
    
     

    可以看到,无论是否使用CommandBehavior.CloseConnection,两个方法都没有在最终关闭连接,但是它们不关闭连接的原因并不相同。准备好了两个方法之后,就从主方法中分别调用这两个方法来进行测试,以查看从使用了CommandBehavior.CloseConnection的方法中返回的SqlDataReader对象是否在关闭的同时自动关闭连接,如代码9-3所示。

    编写测试方法进行测试:

    class UseCommandBehavior
    
    {
    
    /// <summary>
    
    /// 测试方法
    
    /// </summary>
    
    static void Main(string[] args)
    
    {
    
    //建立连接
    
    SqlConnection con = new SqlConnection(conn_String);
    
    try
    
    {
    
    //测试使用了CommandBehavior.CloseConnection的方法
    
    Console.WriteLine("测试使用了CommandBehavior.
    
    CloseConnection的方法:");
    
    SqlDataReader sdr = GetReader_CloseConnection(con);
    
    while (sdr.Read()) { }
    
    sdr.Close();
    
    Console.WriteLine("读取完毕后的连接状态:" + con.State.ToString());
    
    //测试没有使用CommandBehavior.CloseConnection的方法
    
    Console.WriteLine("测试没有使用CommandBehavior.
    
    CloseConnection的方法:");
    
    SqlDataReader sdr1 = GetReader_NoCloseConnection(con);
    
    while (sdr1.Read()) { }
    
    sdr1.Close();
    
    Console.WriteLine("读取完毕后的连接状态:" +
    
    con.State.ToString());
    
    Console.Read();
    
    }
    
    finally
    
    {
    
    //确保连接被关闭
    
    if (con.State != ConnectionState.Closed)
    
    con.Close();
    
    }
    
    }
    
    }

    下面是代码的执行结果:

    测试使用了CommandBehavior.CloseConnection的方法:

    读取完毕后的连接状态:Closed

    测试没有使用CommandBehavior.CloseConnection的方法:

    读取完毕后的连接状态:Open

    正如读者所看到的,使用了CommandBehavior.CloseConnection得到的SqlDataReader对象,在关闭的同时会自动地关闭其依赖的数据库连接对象,这个特性解决了数据访问层编写中的困境。

    答案

    CommandBehavior.CloseConnection解决了流读取数据模式下,数据库连接不能有效关闭的情况。当某个XXXDataReader对象在生成时使用了CommandBehavior.CloseConnection,那数据库连接将在XXXDataReader对象关闭时自动关闭。

  • 相关阅读:
    奔驰4-MATIC和奥迪quattro的区别和共同点是什么(杂记)
    ibatis.net:QueryForObject(转)
    iBatis入门(转)
    javax.servlet.ServletException: java.lang.NullPointerException 空指针异常
    报错:Action[/statisticsManage] does not contain specified method (check logs)
    eclipse下,64位tomcat报错(转)
    Resource '/servers' does not exist 问题的解决(转)
    Ext.data.SimpleStore的使用方法
    combo的displayField和valueField属性
    Exception occurred during processing request: null java.lang.NullPointerException
  • 原文地址:https://www.cnblogs.com/IT-Monkey/p/4112352.html
Copyright © 2020-2023  润新知