RefCountingDataReader ?

Topics: Data Access Application Block
May 2, 2010 at 12:01 PM


until EntLib 5 I used to use

SqlDataReader reader = (SqlDataReader) _database.ExecuteReader(select);
if (reader.HasRows)

In EntLib 5 using this code I get the following exception:

{"Unable to cast object of type 'Microsoft.Practices.EnterpriseLibrary.Data.RefCountingDataReader' to type 'System.Data.SqlClient.SqlDataReader'."}


RefCountingDataReader reader = (RefCountingDataReader) _database.ExecuteReader(select);
if (((SqlDataReader)reader.InnerReader).HasRows)

What's the intent of RefCountingDataReader and the resulting behaviour?



May 2, 2010 at 6:19 PM
This was a bug fix. In Entlib 3.0, we added support for System.TransactionScope. It turns out we did it wrong, and caused some intermittent failures in large systems under load. To the point that the bug cost some large companies quite a bit of money in figuring out the problem, and they ended up removing entlib from their system completely. Part of this fix required that we do reference counting on database connections that we own so that we don't close them down until they're no longer used (which was the bug). As such, we needed to wrap data readers so we could properly detect when a reader was closed and manage our connections correctly. The bug was actually posted here on codeplex somewhere, but I forget the work item number.
May 2, 2010 at 7:00 PM

Thanks for your reply.

So my "workaround" is now the official new solution to be able to cast to WhatEverDataReader?


May 3, 2010 at 2:02 AM

Yep. I'd probably wrap it in an extension method or something to make the syntax a little nicer.

Just make sure you put any data readers you get out of DAAB in a using statement or remember to call close on it, and be sure to close the original, outer datareader, not the inner one. Otherwise you'll screw up the connection management.


Dec 17, 2010 at 4:26 AM

Dear Sir :

Thanks for your sharing.

I've meeted the same problem and I found out another article to solve it.

This is my Blog for recording this problem.


My sample code is  ----------------------------------------------------------------------------------

Imports Microsoft.Practices.EnterpriseLibrary.Data   '-- using EntLib 5.0
Imports System.Data


Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim db As Database = DatabaseFactory.CreateDatabase("Your_ConnectionString") 

        Dim sqlstr As String = "Select top 10 id,title From test"
        Using I_dr As RefCountingDataReader = CType(db.ExecuteReader(CommandType.Text, sqlstr), RefCountingDataReader)

            GridView1.DataSource = DirectCast(I_dr.InnerReader, System.Data.SqlClient.SqlDataReader)

            '--Thanks these friends help to solve this problem:
        End Using

    End Sub