//--------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- namespace System.Data.EntityClient { using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Data.Common; using System.Diagnostics; /// /// A data reader class for the entity client provider /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] public class EntityDataReader : DbDataReader, IExtendedDataRecord { // The command object that owns this reader private EntityCommand _command; private CommandBehavior _behavior; // Store data reader, _storeExtendedDataRecord points to the same reader as _storeDataReader, it's here to just // save the casting wherever it's used private DbDataReader _storeDataReader; private IExtendedDataRecord _storeExtendedDataRecord; /// /// The constructor for the data reader, each EntityDataReader must always be associated with a EntityCommand and an underlying /// DbDataReader. It is expected that EntityDataReader only has a reference to EntityCommand and doesn't assume responsibility /// of cleaning the command object, but it does assume responsibility of cleaning up the store data reader object. /// internal EntityDataReader(EntityCommand command, DbDataReader storeDataReader, CommandBehavior behavior) : base() { Debug.Assert(command != null && storeDataReader != null); this._command = command; this._storeDataReader = storeDataReader; this._storeExtendedDataRecord = storeDataReader as IExtendedDataRecord; this._behavior = behavior; } /// /// Get the depth of nesting for the current row /// public override int Depth { get { return this._storeDataReader.Depth; } } /// /// Get the number of columns in the current row /// public override int FieldCount { get { return this._storeDataReader.FieldCount; } } /// /// Get whether the data reader has any rows /// public override bool HasRows { get { return this._storeDataReader.HasRows; } } /// /// Get whether the data reader has been closed /// public override bool IsClosed { get { return this._storeDataReader.IsClosed; } } /// /// Get whether the data reader has any rows /// public override int RecordsAffected { get { return this._storeDataReader.RecordsAffected; } } /// /// Get the value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value public override object this[int ordinal] { get { return this._storeDataReader[ordinal]; } } /// /// Get the value of a column with the given name /// /// The name of the column to retrieve the value public override object this[string name] { get { EntityUtil.CheckArgumentNull(name, "name"); return this._storeDataReader[name]; } } /// /// Get the number of non-hidden fields in the reader /// public override int VisibleFieldCount { get { return this._storeDataReader.VisibleFieldCount; } } /// /// DataRecordInfo property describing the contents of the record. /// public DataRecordInfo DataRecordInfo { get { if (null == this._storeExtendedDataRecord) { // if a command has no results (e.g. FunctionImport with no return type), // there is nothing to report. return null; } return this._storeExtendedDataRecord.DataRecordInfo; } } /// /// Close this data reader /// public override void Close() { if (this._command != null) { this._storeDataReader.Close(); // Notify the command object that we are closing, so clean up operations such as copying output parameters can be done this._command.NotifyDataReaderClosing(); if ((this._behavior & CommandBehavior.CloseConnection) == CommandBehavior.CloseConnection) { Debug.Assert(this._command.Connection != null); this._command.Connection.Close(); } this._command = null; } } /// /// Releases the resources used by this data reader /// /// true to release both managed and unmanaged resources, false to release only unmanaged resources protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { this._storeDataReader.Dispose(); } } /// /// Get the boolean value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The boolean value public override bool GetBoolean(int ordinal) { return this._storeDataReader.GetBoolean(ordinal); } /// /// Get the byte value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The byte value public override byte GetByte(int ordinal) { return this._storeDataReader.GetByte(ordinal); } /// /// Get the byte array value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The index within the row to start reading /// The buffer to copy into /// The index in the buffer indicating where the data is copied into /// The maximum number of bytes to read /// The actual number of bytes read public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length) { return this._storeDataReader.GetBytes(ordinal, dataOffset, buffer, bufferOffset, length); } /// /// Get the char value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The char value public override char GetChar(int ordinal) { return this._storeDataReader.GetChar(ordinal); } /// /// Get the char array value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The index within the row to start reading /// The buffer to copy into /// The index in the buffer indicating where the data is copied into /// The maximum number of bytes to read /// The actual number of characters read public override long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length) { return this._storeDataReader.GetChars(ordinal, dataOffset, buffer, bufferOffset, length); } /// /// Get the name of the data type of the column with the given ordinal /// /// The ordinal of the column to retrieve the name of the data type /// The name of the data type of the column public override string GetDataTypeName(int ordinal) { return this._storeDataReader.GetDataTypeName(ordinal); } /// /// Get the datetime value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The datetime value public override DateTime GetDateTime(int ordinal) { return this._storeDataReader.GetDateTime(ordinal); } /// /// Get the data reader of a column with the given ordinal /// /// The ordinal of the column to retrieve the reader /// The data reader protected override DbDataReader GetDbDataReader(int ordinal) { return this._storeDataReader.GetData(ordinal); } /// /// Get the decimal value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The decimal value public override decimal GetDecimal(int ordinal) { return this._storeDataReader.GetDecimal(ordinal); } /// /// Get the double value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The double value public override double GetDouble(int ordinal) { return this._storeDataReader.GetDouble(ordinal); } /// /// Get the data type of the column with the given ordinal /// /// The ordinal of the column to retrieve the data type /// The data type of the column public override Type GetFieldType(int ordinal) { return this._storeDataReader.GetFieldType(ordinal); } /// /// Get the float value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The float value public override float GetFloat(int ordinal) { return this._storeDataReader.GetFloat(ordinal); } /// /// Get the guid value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The guid value public override Guid GetGuid(int ordinal) { return this._storeDataReader.GetGuid(ordinal); } /// /// Get the int16 value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The int16 value public override short GetInt16(int ordinal) { return this._storeDataReader.GetInt16(ordinal); } /// /// Get the int32 value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The int32 value public override int GetInt32(int ordinal) { return this._storeDataReader.GetInt32(ordinal); } /// /// Get the int64 value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The int64 value public override long GetInt64(int ordinal) { return this._storeDataReader.GetInt64(ordinal); } /// /// Get the name of a column with the given ordinal /// /// The ordinal of the column to retrieve the name /// The name public override string GetName(int ordinal) { return this._storeDataReader.GetName(ordinal); } /// /// Get the ordinal of a column with the given name /// /// The name of the column to retrieve the ordinal /// The ordinal of the column public override int GetOrdinal(string name) { EntityUtil.CheckArgumentNull(name, "name"); return this._storeDataReader.GetOrdinal(name); } /// /// implementation for DbDataReader.GetProviderSpecificFieldType() method /// /// /// [EditorBrowsableAttribute(EditorBrowsableState.Never)] override public Type GetProviderSpecificFieldType(int ordinal) { return _storeDataReader.GetProviderSpecificFieldType(ordinal); } /// /// implementation for DbDataReader.GetProviderSpecificValue() method /// /// /// [EditorBrowsableAttribute(EditorBrowsableState.Never)] public override object GetProviderSpecificValue(int ordinal) { return _storeDataReader.GetProviderSpecificValue(ordinal); } /// /// implementation for DbDataReader.GetProviderSpecificValues() method /// /// /// [EditorBrowsableAttribute(EditorBrowsableState.Never)] public override int GetProviderSpecificValues(object[] values) { return _storeDataReader.GetProviderSpecificValues(values); } /// /// Get the DataTable that describes the columns of this data reader /// /// The DataTable describing the columns public override DataTable GetSchemaTable() { return this._storeDataReader.GetSchemaTable(); } /// /// Get the string value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The string value public override string GetString(int ordinal) { return this._storeDataReader.GetString(ordinal); } /// /// Get the value of a column with the given ordinal /// /// The ordinal of the column to retrieve the value /// The value public override object GetValue(int ordinal) { return this._storeDataReader.GetValue(ordinal); } /// /// Get the values for all the columns and for the current row /// /// The array where values are copied into /// The number of System.Object instances in the array public override int GetValues(object[] values) { return this._storeDataReader.GetValues(values); } /// /// Get whether the value of a column is DBNull /// /// The ordinal of the column to retrieve the value /// true if the column value is DBNull public override bool IsDBNull(int ordinal) { return this._storeDataReader.IsDBNull(ordinal); } /// /// Move the reader to the next result set when reading a batch of statements /// /// true if there are more result sets public override bool NextResult() { try { return this._storeDataReader.NextResult(); } catch (Exception e) { if (EntityUtil.IsCatchableExceptionType(e)) { throw EntityUtil.CommandExecution(System.Data.Entity.Strings.EntityClient_StoreReaderFailed, e); } throw; } } /// /// Move the reader to the next row of the current result set /// /// true if there are more rows public override bool Read() { return this._storeDataReader.Read(); } /// /// Get an enumerator for enumerating results over this data reader /// /// An enumerator for this data reader public override IEnumerator GetEnumerator() { return this._storeDataReader.GetEnumerator(); } /// /// Used to return a nested DbDataRecord. /// public DbDataRecord GetDataRecord(int i) { if (null == this._storeExtendedDataRecord) { Debug.Assert(this.FieldCount == 0, "we have fields but no metadata?"); // for a query with no results, any request is out of range... EntityUtil.ThrowArgumentOutOfRangeException("i"); } return this._storeExtendedDataRecord.GetDataRecord(i); } /// /// Used to return a nested result /// public DbDataReader GetDataReader(int i) { return this.GetDbDataReader(i); } } }