其用在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对象关闭时自动关闭。

CommandBehavior.CloseConnection使用的更多相关文章

  1. CommandBehavior.CloseConnection

    cmd.commandTimeout设置为了1秒,sql执行了很长时间还没有超时, cmd.ExecuteReader(CommandBehavior.CloseConnection)这样就会立马重现 ...

  2. cmd.ExecuteReader(CommandBehavior.CloseConnection)

    有些开发人员坚持认为,如果您设置 CommandBehavior.CloseConnection 选项,则 DataReader 及其相关联的连接会在 DataReader 完成数据读取时自动关闭.这 ...

  3. C#使用SqlDataReader读取数据库数据时CommandBehavior.CloseConnection参数的作用

    主要用在ExecuteReader(c)中,如果想要返回对象前不关闭数据库连接,须要用CommandBehavior.CloseConnection: CloseConnection解决了流读取数据模 ...

  4. CommandBehavior.CloseConnection的使用

    CommandBehavior.CloseConnection的使用 分析问题 由于流模式读取数据库的特点,在具体应用时很难确定数据库连接何时才能被关闭,因为读取的动作是连续进行的,下面是一个常见的数 ...

  5. CommandBehavior.CloseConnection有何作用

    其用在ExecuteReader(c)中,返回对象前不能关闭数据库连接,须用CommandBehavior.CloseConnection: 这是一个关于实际知识点的问题,面试官考查的是应聘者数据库访 ...

  6. 浅谈CommandBehavior枚举的独特之处

    提供对查询结果和查询对数据库的影响 此枚举有一个 FlagsAttribute 属性,通过该属性可使其成员值按位组合. 命名空间:  System.Data程序集:  System.Data(在 Sy ...

  7. Microsoft Visual Studio 2017 for Mac Preview 下载+安装+案例Demo

    目录: 0. 前言 1. 在线安装器 2. 安装VS 3. HelloWorld 4. ASP.NET MVC 5. 软件下载 6. 结尾 0. 前言: 工作原因,上下班背着我的雷神,一个月瘦了10斤 ...

  8. 完美解决CodeSmith无法获取MySQL表及列Description说明注释的方案

    问题描述: CodeSmith是现在比较实用的代码生成器,但是我们发现一个问题: 使用CodeSmith编写MySQL模板的时候,会发现一个问题:MySQL数据表中的列说明获取不到,也就是column ...

  9. .NET基础拾遗(6)ADO.NET与数据库开发基础

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开发基 ...

随机推荐

  1. CodeForces 220B(B. Little Elephant and Array)

    http://codeforces.com/contest/220/problem/B 题意:给出一个数组,给出m组询问,问区间中出现a[i] 次的有多少个. sl: 很显然的离线问题了. 大视野菜花 ...

  2. hdu2852 KiKi's K-Number

    题意:给定三个操作添加删除查询大于a的的第k大值----树状数组的逆向操作 给定a利用BIT查询有多少值比a小,这样比a大的k大值就应该有k+sum(a)个小于他的值 因此可以二分枚举k大值看看是不是 ...

  3. vim中256色的配色表

    vim貌似支持的颜色很有限.white  black  yellow  cyan   magenta   blue   grey   green   red,大多数颜色前面都可以加light 或者 d ...

  4. Spring Boot配置文件规则以及使用方法官方文档查找以及Spring项目的官方文档查找方法

    比如要使用Spring Boot实现一个功能,最直接的方式是Google,但是往往搜索出来的都比较乱,关键是乱在不同的版本上,比如1.x版本和2.x版本的配置是不一样的.最明显区别是在使用Thymel ...

  5. bzoj1072【SCOI2007】排列perm

    1072: [SCOI2007]排列perm Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1479  Solved: 928 [id=1072&q ...

  6. 服务器Hot Spare热备

    Hot Spare:热备用 当一个正在使用的磁盘发生故障后,一个空闲.加电并待机的磁盘将马上代替此故障盘,此方法就是热备用.热备用磁盘上不存储任何的用户数据,最多可以有8个磁盘作为热备用磁盘.一个热备 ...

  7. 论文笔记:目标追踪-CVPR2014-Adaptive Color Attributes for Real-time Visual Tracking

    基于自适应颜色属性的目标追踪 Adaptive Color Attributes for Real-Time Visual Tracking 基于自适应颜色属性的实时视觉追踪 3月讲的第一篇论文,个人 ...

  8. 调试JDK源代码-一步一步看HashMap怎么Hash和扩容

    调试JDK源代码-一步一步看HashMap怎么Hash和扩容 调试JDK源代码-ConcurrentHashMap实现原理 调试JDK源代码-HashSet实现原理 调试JDK源代码-调试JDK源代码 ...

  9. 模块化开发(二)--- seaJs入门学习

    SeaJS是一个基于CMD模块定义规范实现一个模块系统加载器   [CMD规范](https://github.com/cmdjs/specification/blob/master/draft/mo ...

  10. 360p以上

    请选择200MB以内,360p以上,时长3秒到300秒的文件.(支持格式:mp4.3gp.avi.mov.m4v.mkv文件)