The IDataReader Interface


The IDataReader Interface

Providing a solid DataReader is core to providing a reliable .NET managed data provider. DataReaders provide forward-only access over the ResultSets obtained by executing database commands. They also provide access to values for the fields in each DataRow through strongly typed accessor methods. Examples of strongly typed accessors are GetInt32, GetString, and so on. Additionally, DataAdapters use DataReaders to fill the DataTables in a DataSet. The Data Access Application Block returns a class that implements the IDataReader interface when the ExecuteReader method is called on a database provider.

The XmlFileDataReader is the implementation of the IDataReader interface for the .NET managed data provider for XML files. However, before showing you some of the code for this DataReader, I must provide a disclaimer: I have not made this DataReader as efficient as it should be. It uses a private DataSet member variable to read and write data from and to XML files, and uses the DataSet internally to return the values for column fields. While it is not optimized for performance, this DataReader will serve the purpose for providing a valid implementation for the IDataReader interface so a database provider can be created and used.

The DataReader could be enhanced to perform better. To do so, it would need to use the same inference process that .NET uses to determine the relational structure of the data when loading from XML. The inference process first determines, from the XML document, which elements will be inferred as tables. From the remaining XML, the inference process determines the columns for those tables. For nested tables, the inference process generates nested DataRelation and ForeignKeyConstraint objects. The following assumptions must be made during this process.

  • Elements that have attributes are inferred as tables.

  • Elements that have child elements are inferred as tables.

  • Elements that repeat are inferred as a single table.

  • If the document (root) element has no attributes, and no child elements that would be inferred as columns, it is inferred as a DataSet. Otherwise, the document element is inferred as a table.

  • Attributes are inferred as columns.

  • Elements that have no attributes or child elements and do not repeat are inferred as columns.

  • For elements that are inferred as tables that are nested in other elements also inferred as tables, a nested DataRelation is created between the two tables. A new, primary key column named TableName_Id is added to both tables and used by the DataRelation. A ForeignKeyConstraint is created between the two tables using the TableName_Id column.

  • For elements that are inferred as tables and that contain text but have no child elements, a new column named TableName_Text is created for the text of each of the elements. If an element is inferred as a table and has text as well as child elements, the text is ignored.

Listing B.3 provides an excerpt of the XmlFileDataReader.

Listing B.3. XmlFileDataReader Implements IDataReader

[C#] public class XmlFileDataReader : IDataReader {     ...     public bool NextResult()     {          return (tableNum < dataSet.Tables.Count);     }     public void Close()     {          closed = true;          if (xmlFileConnection != null) xmlFileConnection.Close();     }     internal void GetXmlFile(string strCommand)     {          fileName = strCommand;          try          {               dataSet.ReadXml(strCommand);               rowNum = -1;               closed = false;          }          catch (Exception ex)          {               throw new               ApplicationException               (SR.ExceptionLoadXMLFile(command, ex.Message));          }     }     internal XmlReader XmlReader     {          get          {               try               {                    XmlReader retVal = new XmlTextReader                          (new System.IO.StringReader                          (dataSet.GetXml()));                    return retVal;               }               catch (Exception ex)               {                    throw new                    ApplicationException(                    SR.ExceptionCreateReader(ex.Message));               }          }     }     public bool Read()     {          bool bRetVal = false;          if (closed) return bRetVal;          if (rowNum < (dataSet.Tables[tableNum].Rows.Count -1))          {               bRetVal = true;               rowNum++;          }          else          {               tableNum++;               rowNum = -1;          }          return bRetVal;     }     public int GetInt32(int i)     {          return (Int32)GetValue(i);     }     public byte GetByte(int i)     {          return (Byte)GetValue(i);     }     ... } [Visual Basic]     Public Class XmlFileDataReader : Implements IDataReader     ...     Public Function NextResult() As Boolean _               Implements IDataReader.NextResult          Return (tableNum < dataSet.Tables.Count)     End Function     Public Sub Close() Implements IDataReader.Close          closed = True          If Not xmlFileConnection Is Nothing Then               xmlFileConnection.Close()          End If     End Sub     Friend Sub GetXmlFile(ByVal strCommand As String)          fileName = strCommand          Try               dataSet.ReadXml(strCommand)               rowNum = -1               closed = False          Catch ex As Exception               Throw New ApplicationException _                     (SR.ExceptionLoadXMLFile(command, ex.Message))          End Try     End Sub     Friend ReadOnly Property XmlReader() As XmlReader          Get               Try                    Dim retVal As XmlReader = New XmlTextReader _                          (New _                              System.IO.StringReader(dataSet.GetXml()))                    Return retVal               Catch ex As Exception                    Throw New _                         ApplicationException _                         (SR.ExceptionCreateReader(ex.Message))               End Try          End Get     End Property     Public Function Read() As Boolean Implements IDataReader.Read          Dim bRetVal As Boolean = False          If closed Then               Return bRetVal          End If          If rowNum < (dataSet.Tables(tableNum).Rows.Count -1) Then               bRetVal = True               rowNum += 1          Else               tableNum += 1               rowNum = -1          End If          Return bRetVal     End Function     Public Function GetInt32(ByVal i As Integer) As Integer          Return CInt(GetValue(i))     End Function     Public Function GetByte(ByVal i As Integer) As Byte          Return CType(GetValue(i), Byte)     End Function     ... End Class




Fenster Effective Use of Microsoft Enterprise Library(c) Building Blocks for Creating Enterprise Applications and Services 2006
Effective Use of Microsoft Enterprise Library: Building Blocks for Creating Enterprise Applications and Services
ISBN: 0321334213
EAN: 2147483647
Year: 2004
Pages: 103
Authors: Len Fenster

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net