当前位置:主页   - 电脑 - 网站开发 - ASP.Net
Is this a MS EnterLib DAAB BUG or not?
来源:网络   作者:   更新时间:2012-06-01
收藏此页】    【字号    】    【打印】    【关闭

  开门见山,使用MS Enterprise Library的DAAB(Data Access Application Block)获取数据时抛出异常。具体场景如下,通过Database对象的ExecuteReader执行两段Select语句,前一句是不合法的,后一句是正确的。为了避免第一次执行出错导致程序的终止,特意将其放到Try/Catch酷快中。两次数据库操作通过TrsanctionScope的形式纳入同一个Transaction中,具体的代码如下所示。 

class Program
{
    static void Main()
    {

        string invalidSql = "SELECT * FROM {InvalidTable}";
        string validSql = "SELECT * FROM {ValidTable}";

        Database db = DatabaseFactory.CreateDatabase();
        using (TransactionScope scope = new TransactionScope())
        {
            DbCommand commandWithInvalidSql = db.GetSqlStringCommand(invalidSql);
            DbCommand commandWithValidSql = db.GetSqlStringCommand(validSql);

            try
            {
                db.ExecuteReader(commandWithInvalidSql);
            }
            catch
            { }

            db.ExecuteReader(commandWithValidSql);
        }
    }
} 

  但是在执行第二个ExecuteReader方法的时候却抛出如下一个InvalidOperationException(如下图),错误消息为:“ExecuteReader requires an open and available Connection. The connection's current state is closed.” 

Is this a MS EnterLib DAAB BUG or not?

  图片看不清楚?请点击这里查看原图(大图)。

  原因出在这里:在ExecuteReader中,相应的ADO.NET代码放在try|catch中,当异常抛出后,相应的DbConnect会被关闭。但是由于在我的代码中,两次ExecuteReader的调用是在一个相同的Ambient Transaction中执行的,DAAB在内部采用相同的DbTransaction执行这两项操作,当执行第一项操作时,由于出现异常导致DbConnect关闭,使用相同DbConnect的第二项操作肯定会失败。

public virtual IDataReader ExecuteReader(DbCommand command)
{
    ConnectionWrapper wrapper = GetOpenConnection(false);

    try
    {
//
// JS-L: I moved the PrepareCommand inside the try because it can fail.
//
PrepareCommand(command, wrapper.Connection);

//
// If there is a current transaction, we'll be using a shared connection, so we don't
// want to close the connection when we're done with the reader.
//
if (Transaction.Current != null)
    return DoExecuteReader(command, CommandBehavior.Default);
else
    return DoExecuteReader(command, CommandBehavior.CloseConnection);
    }
    catch
    {
wrapper.Connection.Close();
throw;
    }
}

  我不清楚微软在设计的时候,是因为没有考虑到这种场景呢,还是不得以而为之,或者是出于其他因素的考虑,大家有何见解。

其它资源
来源声明

版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明