Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Query / ResultAssembly / BridgeDataReader.cs / 1305376 / BridgeDataReader.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- namespace System.Data.Query.ResultAssembly { using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.Common; using System.Data.Common.CommandTrees; using System.Data.Common.Internal.Materialization; using System.Data.Metadata.Edm; using System.Data.Query.InternalTrees; using System.Data.Query.PlanCompiler; using System.Diagnostics; using System.Text; using System.Threading; using System.Data.Entity; using System.Linq; using System.Data.Mapping; using System.Data.Common.Utils; ////// DbDataReader functionality for the bridge. /// internal sealed class BridgeDataReader : DbDataReader, IExtendedDataRecord { #region private state ////// Object that holds the state needed by the coordinator and the root enumerator /// private readonly ShaperShaper; /// /// The coordinator we're responsible for returning results for. /// private readonly CoordinatorFactoryCoordinatorFactory; /// /// The default record (pre-read/past-end) state /// private readonly RecordState DefaultRecordState; ////// We delegate to this on our getters, to avoid duplicate code. /// private readonly BridgeDataRecord DataRecord; ////// Do we have a row to read? Determined in the constructor and /// should not be changed. /// private readonly bool _hasRows; ////// Set to true only when we've been closed through the Close() method /// private bool _isClosed; #endregion #region constructors ////// Constructor used by the ResultColumn when doing GetValue, and by the Create factory /// method. /// /// /// internal BridgeDataReader(Shapershaper, CoordinatorFactory coordinatorFactory, int depth) : base() { Debug.Assert(null != shaper, "null shaper?"); Debug.Assert(null != coordinatorFactory, "null coordinatorFactory?"); Shaper = shaper; CoordinatorFactory = coordinatorFactory; DataRecord = new BridgeDataRecord(shaper, depth); // To determine whether there are any rows for this coordinator at this place in // the root enumerator, we pretty much just look at it's current record (we'll read // one if there isn't one waiting) and if it matches our coordinator, we've got rows. _hasRows = false; if (!Shaper.DataWaiting) { Shaper.DataWaiting = Shaper.RootEnumerator.MoveNext(); } if (Shaper.DataWaiting) { RecordState currentRecord = Shaper.RootEnumerator.Current; if (null != currentRecord) { _hasRows = (currentRecord.CoordinatorFactory == CoordinatorFactory); } } // Once we've created the root enumerator, we can get the default record state DefaultRecordState = coordinatorFactory.GetDefaultRecordState(Shaper); Debug.Assert(null != DefaultRecordState, "no default?"); } /// /// The primary factory method to produce the BridgeDataReader; given a store data /// reader and a column map, create the BridgeDataReader, hooking up the IteratorSources /// and ResultColumn Hierarchy. All construction of top level data readers go through /// this method. /// /// /// ///static internal DbDataReader Create(DbDataReader storeDataReader, ColumnMap columnMap, MetadataWorkspace workspace) { Debug.Assert(storeDataReader != null, "null storeDataReaders?"); Debug.Assert(columnMap != null, "null columnMap?"); Debug.Assert(workspace != null, "null workspace?"); System.Data.Common.QueryCache.QueryCacheManager cacheManager = workspace.GetQueryCacheManager(); const System.Data.Objects.MergeOption NoTracking = System.Data.Objects.MergeOption.NoTracking; ShaperFactory shaperFactory = Translator.TranslateColumnMap (cacheManager, columnMap, workspace, null, NoTracking, true); Shaper recordShaper = shaperFactory.Create(storeDataReader, null, workspace, System.Data.Objects.MergeOption.NoTracking, true); DbDataReader result = new BridgeDataReader(recordShaper, recordShaper.RootCoordinator.TypedCoordinatorFactory, 0); return result; } #endregion #region helpers /// /// Implicitly close this (nested) data reader; will be called whenever /// the user has done a GetValue() or a Read() on a parent reader/record /// to ensure that we consume all our results. We do that because we /// our design requires us to be positioned at the next nested reader's /// first row. /// internal void CloseImplicitly() { Consume(); DataRecord.CloseImplicitly(); } ////// Reads to the end of the source enumerator provided /// private void Consume() { while (ReadInternal()) ; } ////// Figure out the CLR type from the TypeMetadata object; For scalars, /// we can get this from the metadata workspace, but for the rest, we /// just guess at "Object". You need to use the DataRecordInfo property /// to get better information for those. /// /// ///internal static Type GetClrTypeFromTypeMetadata(TypeUsage typeUsage) { Type result; PrimitiveType primitiveType; if (TypeHelpers.TryGetEdmType (typeUsage, out primitiveType)) { result = primitiveType.ClrEquivalentType; } else { if (TypeSemantics.IsReferenceType(typeUsage)) { result = typeof(EntityKey); } else if (TypeUtils.IsStructuredType(typeUsage)) { result = typeof(DbDataRecord); } else if (TypeUtils.IsCollectionType(typeUsage)) { result = typeof(DbDataReader); } else { result = typeof(object); } } return result; } #endregion #region data reader specific properties and methods /// /// implementation for DbDataReader.Depth property /// override public int Depth { get { AssertReaderIsOpen("Depth"); return DataRecord.Depth; } } ////// implementation for DbDataReader.HasRows property /// override public bool HasRows { get { AssertReaderIsOpen("HasRows"); return _hasRows; } } ////// implementation for DbDataReader.IsClosed property /// override public bool IsClosed { get { // Rather that try and track this in two places; we just delegate // to the data record that we constructed; it has more reasons to // have to know this than we do in the data reader. (Of course, // we look at our own closed state too...) return ((_isClosed) || DataRecord.IsClosed); } } ////// implementation for DbDataReader.RecordsAffected property /// override public int RecordsAffected { get { int result = -1; // For nested readers, return -1 which is the default for queries. // We defer to the store reader for rows affected count. Note that for queries, // the provider is generally expected to return -1. // if (DataRecord.Depth == 0) { result = Shaper.Reader.RecordsAffected; } return result; } } ////// Ensures that the reader is actually open, and throws an exception if not /// private void AssertReaderIsOpen(string methodName) { if (IsClosed) { if (DataRecord.IsImplicitlyClosed) { throw EntityUtil.ImplicitlyClosedDataReaderError(); } if (DataRecord.IsExplicitlyClosed) { throw EntityUtil.DataReaderClosed(methodName); } } } ////// implementation for DbDataReader.Close() method /// override public void Close() { // Make sure we explicitly closed the data record, since that's what // where using to track closed state. DataRecord.CloseExplicitly(); if (!_isClosed) { _isClosed = true; if (0 == DataRecord.Depth) { // If we're the root collection, we want to ensure the remainder of // the result column hierarchy is closed out, to avoid dangling // references to it, should it be reused. We also want to physically // close out the source reader as well. Shaper.Reader.Close(); } else { // For non-root collections, we have to consume all the data, or we'll // not be positioned propertly for what comes afterward. Consume(); } } } ////// implementation for DbDataReader.GetEnumerator() method /// [EditorBrowsableAttribute(EditorBrowsableState.Never)] override public IEnumerator GetEnumerator() { IEnumerator result = new DbEnumerator((IDataReader)this, true); // We always want to close the reader; return result; } ////// implementation for DbDataReader.GetSchemaTable() method /// /// This is awaiting some common code /// ////// GetSchemaTable is not supported at this time override public DataTable GetSchemaTable() { throw EntityUtil.NotSupported(System.Data.Entity.Strings.ADP_GetSchemaTableIsNotSupported); } ////// implementation for DbDataReader.NextResult() method /// /// since the bridge currently doesn't support multiple results in a /// single command, this always returns false. /// ///override public bool NextResult() { AssertReaderIsOpen("NextResult"); // Consume results in the source collection to ensure that the // store reader and the bridge data reader are in the same state. // If we are not a root reader, we do not 'own' the store reader // and do nothing. if (0 == DataRecord.Depth) { // NOTE:: this is required to ensure that output parameter values // are set in SQL Server, and other providers where they come after // the results. CommandHelper.ConsumeReader(Shaper.Reader); } else { // For nested readers, make sure we're positioned properly for // the following columns... Consume(); } // SQLBUDT #631726 - ensure we close the records that may be // outstanding... // SQLBUDT #632494 - do this after we consume the underlying reader // so we don't run result assembly through it... CloseImplicitly(); // Reset any state on our attached data record, since we've now // gone past the end of the reader. DataRecord.SetRecordSource(null, false); // NOTE: if the bridge ever supports multiple results in a single // command, we'll need to change this, but for now we can't // ever have another result. return false; } /// /// implementation for DbDataReader.Read() method /// ///override public bool Read() { AssertReaderIsOpen("Read"); // First of all we need to inform each of the nested records that // have been returned that they're "implicitly" closed -- that is // we've moved on. This will also ensure that any records remaining // in any active nested readers are consumed DataRecord.CloseImplicitly(); // OK, now go ahead and advance the source enumerator and set the // record source up bool result = ReadInternal(); DataRecord.SetRecordSource(Shaper.RootEnumerator.Current, result); return result; } /// /// Internal read method; does the work of advancing the root enumerator /// as needed and determining whether it's current record is for our /// coordinator. The public Read method does the assertions and such that /// we don't want to do when we're called from internal methods to do things /// like consume the rest of the reader's contents. /// /// ///private bool ReadInternal() { bool result = false; // If there's nothing waiting for the root enumerator, then attempt // to advance it. if (!Shaper.DataWaiting) { Shaper.DataWaiting = Shaper.RootEnumerator.MoveNext(); } // If we have some data (we may have just read it above) then figure // out who it belongs to-- us or someone else. We also skip over any // records that are for our children (nested readers); if we're being // asked to read, it's too late for them to read them. while (Shaper.DataWaiting && Shaper.RootEnumerator.Current.CoordinatorFactory != CoordinatorFactory && Shaper.RootEnumerator.Current.CoordinatorFactory.Depth > CoordinatorFactory.Depth) { Shaper.DataWaiting = Shaper.RootEnumerator.MoveNext(); } if (Shaper.DataWaiting) { // We found something, go ahead and indicate to the shaper we want // this record, set up the data record, etc. if (Shaper.RootEnumerator.Current.CoordinatorFactory == CoordinatorFactory) { Shaper.DataWaiting = false; Shaper.RootEnumerator.Current.AcceptPendingValues(); result = true; } } return result; } #endregion #region metadata properties and methods /// /// implementation for DbDataReader.DataRecordInfo property /// public DataRecordInfo DataRecordInfo { get { AssertReaderIsOpen("DataRecordInfo"); DataRecordInfo result; if (DataRecord.HasData) { result = DataRecord.DataRecordInfo; } else { result = DefaultRecordState.DataRecordInfo; } return result; } } ////// implementation for DbDataReader.FieldCount property /// override public int FieldCount { get { AssertReaderIsOpen("FieldCount"); // In this method, we need to return a constant value, regardless // of how polymorphic the result is, because there is a lot of code // in the wild that expects it to be constant; Ideally, we'd return // the number of columns in the actual type that we have, but since // that would probably break folks, I'm leaving it at returning the // base set of columns that all rows will have. int result = DefaultRecordState.ColumnCount; return result; } } ////// implementation for DbDataReader.GetDataTypeName() method /// /// ///override public string GetDataTypeName(int ordinal) { AssertReaderIsOpen("GetDataTypeName"); string result; if (DataRecord.HasData) { result = DataRecord.GetDataTypeName(ordinal); } else { result = TypeHelpers.GetFullName(DefaultRecordState.GetTypeUsage(ordinal)); } return result; } /// /// implementation for DbDataReader.GetFieldType() method /// /// ///override public Type GetFieldType(int ordinal) { AssertReaderIsOpen("GetFieldType"); Type result; if (DataRecord.HasData) { result = DataRecord.GetFieldType(ordinal); } else { result = GetClrTypeFromTypeMetadata(DefaultRecordState.GetTypeUsage(ordinal)); } return result; } /// /// implementation for DbDataReader.GetName() method /// /// ///override public string GetName(int ordinal) { AssertReaderIsOpen("GetName"); string result; if (DataRecord.HasData) { result = DataRecord.GetName(ordinal); } else { result = DefaultRecordState.GetName(ordinal); } return result; } /// /// implementation for DbDataReader.GetOrdinal() method /// /// ///override public int GetOrdinal(string name) { AssertReaderIsOpen("GetOrdinal"); int result; if (DataRecord.HasData) { result = DataRecord.GetOrdinal(name); } else { result = DefaultRecordState.GetOrdinal(name); } return result; } /// /// implementation for DbDataReader.GetProviderSpecificFieldType() method /// /// ////// GetProviderSpecificFieldType is not supported at this time [EditorBrowsableAttribute(EditorBrowsableState.Never)] override public Type GetProviderSpecificFieldType(int ordinal) { throw EntityUtil.NotSupported(); } #endregion #region data record properties and methods //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // // The remaining methods on this class delegate to the inner data record // //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// #region general getter methods and indexer properties ////// implementation for DbDataReader[ordinal] indexer value getter /// override public object this[int ordinal] { get { return DataRecord[ordinal]; } } ////// implementation for DbDataReader[name] indexer value getter /// override public object this[string name] { get { int ordinal = GetOrdinal(name); return DataRecord[ordinal]; } } ////// implementation for DbDataReader.GetProviderSpecificValue() method /// /// ////// GetProviderSpecificValue is not supported at this time [EditorBrowsableAttribute(EditorBrowsableState.Never)] public override object GetProviderSpecificValue(int ordinal) { throw EntityUtil.NotSupported(); } ////// implementation for DbDataReader.GetProviderSpecificValues() method /// /// ////// GetProviderSpecificValues is not supported at this time [EditorBrowsableAttribute(EditorBrowsableState.Never)] public override int GetProviderSpecificValues(object[] values) { throw EntityUtil.NotSupported(); } ////// implementation for DbDataReader.GetValue() method /// /// ///override public Object GetValue(int ordinal) { return DataRecord.GetValue(ordinal); } /// /// implementation for DbDataReader.GetValues() method /// /// ///override public int GetValues(object[] values) { return DataRecord.GetValues(values); } #endregion #region simple scalar value getter methods /// /// implementation for DbDataReader.GetBoolean() method /// /// ///override public bool GetBoolean(int ordinal) { return DataRecord.GetBoolean(ordinal); } /// /// implementation for DbDataReader.GetByte() method /// /// ///override public byte GetByte(int ordinal) { return DataRecord.GetByte(ordinal); } /// /// implementation for DbDataReader.GetChar() method /// /// ///override public char GetChar(int ordinal) { return DataRecord.GetChar(ordinal); } /// /// implementation for DbDataReader.GetDateTime() method /// /// ///override public DateTime GetDateTime(int ordinal) { return DataRecord.GetDateTime(ordinal); } /// /// implementation for DbDataReader.GetDecimal() method /// /// ///override public Decimal GetDecimal(int ordinal) { return DataRecord.GetDecimal(ordinal); } /// /// implementation for DbDataReader.GetDouble() method /// /// ///override public double GetDouble(int ordinal) { return DataRecord.GetDouble(ordinal); } /// /// implementation for DbDataReader.GetFloat() method /// /// ///override public float GetFloat(int ordinal) { return DataRecord.GetFloat(ordinal); } /// /// implementation for DbDataReader.GetGuid() method /// /// ///override public Guid GetGuid(int ordinal) { return DataRecord.GetGuid(ordinal); } /// /// implementation for DbDataReader.GetInt16() method /// /// ///override public Int16 GetInt16(int ordinal) { return DataRecord.GetInt16(ordinal); } /// /// implementation for DbDataReader.GetInt32() method /// /// ///override public Int32 GetInt32(int ordinal) { return DataRecord.GetInt32(ordinal); } /// /// implementation for DbDataReader.GetInt64() method /// /// ///override public Int64 GetInt64(int ordinal) { return DataRecord.GetInt64(ordinal); } /// /// implementation for DbDataReader.GetString() method /// /// ///override public String GetString(int ordinal) { return DataRecord.GetString(ordinal); } /// /// implementation for DbDataReader.IsDBNull() method /// /// ///override public bool IsDBNull(int ordinal) { return DataRecord.IsDBNull(ordinal); } #endregion #region chunking scalar value getter methods /// /// implementation for DbDataReader.GetBytes() method /// /// /// /// /// /// ///override public long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length) { return DataRecord.GetBytes(ordinal, dataOffset, buffer, bufferOffset, length); } /// /// implementation for DbDataReader.GetChars() method /// /// /// /// /// /// ///override public long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length) { return DataRecord.GetChars(ordinal, dataOffset, buffer, bufferOffset, length); } #endregion #region complex type getters /// /// implementation for DbDataReader.GetData() method /// /// ///override protected DbDataReader GetDbDataReader(int ordinal) { return (DbDataReader)DataRecord.GetData(ordinal); } /// /// implementation for DbDataReader.GetDataRecord() method /// /// ///public DbDataRecord GetDataRecord(int ordinal) { return DataRecord.GetDataRecord(ordinal); } /// /// Used to return a nested result /// /// ///public DbDataReader GetDataReader(int ordinal) { return this.GetDbDataReader(ordinal); } #endregion #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- namespace System.Data.Query.ResultAssembly { using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.Common; using System.Data.Common.CommandTrees; using System.Data.Common.Internal.Materialization; using System.Data.Metadata.Edm; using System.Data.Query.InternalTrees; using System.Data.Query.PlanCompiler; using System.Diagnostics; using System.Text; using System.Threading; using System.Data.Entity; using System.Linq; using System.Data.Mapping; using System.Data.Common.Utils; ////// DbDataReader functionality for the bridge. /// internal sealed class BridgeDataReader : DbDataReader, IExtendedDataRecord { #region private state ////// Object that holds the state needed by the coordinator and the root enumerator /// private readonly ShaperShaper; /// /// The coordinator we're responsible for returning results for. /// private readonly CoordinatorFactoryCoordinatorFactory; /// /// The default record (pre-read/past-end) state /// private readonly RecordState DefaultRecordState; ////// We delegate to this on our getters, to avoid duplicate code. /// private readonly BridgeDataRecord DataRecord; ////// Do we have a row to read? Determined in the constructor and /// should not be changed. /// private readonly bool _hasRows; ////// Set to true only when we've been closed through the Close() method /// private bool _isClosed; #endregion #region constructors ////// Constructor used by the ResultColumn when doing GetValue, and by the Create factory /// method. /// /// /// internal BridgeDataReader(Shapershaper, CoordinatorFactory coordinatorFactory, int depth) : base() { Debug.Assert(null != shaper, "null shaper?"); Debug.Assert(null != coordinatorFactory, "null coordinatorFactory?"); Shaper = shaper; CoordinatorFactory = coordinatorFactory; DataRecord = new BridgeDataRecord(shaper, depth); // To determine whether there are any rows for this coordinator at this place in // the root enumerator, we pretty much just look at it's current record (we'll read // one if there isn't one waiting) and if it matches our coordinator, we've got rows. _hasRows = false; if (!Shaper.DataWaiting) { Shaper.DataWaiting = Shaper.RootEnumerator.MoveNext(); } if (Shaper.DataWaiting) { RecordState currentRecord = Shaper.RootEnumerator.Current; if (null != currentRecord) { _hasRows = (currentRecord.CoordinatorFactory == CoordinatorFactory); } } // Once we've created the root enumerator, we can get the default record state DefaultRecordState = coordinatorFactory.GetDefaultRecordState(Shaper); Debug.Assert(null != DefaultRecordState, "no default?"); } /// /// The primary factory method to produce the BridgeDataReader; given a store data /// reader and a column map, create the BridgeDataReader, hooking up the IteratorSources /// and ResultColumn Hierarchy. All construction of top level data readers go through /// this method. /// /// /// ///static internal DbDataReader Create(DbDataReader storeDataReader, ColumnMap columnMap, MetadataWorkspace workspace) { Debug.Assert(storeDataReader != null, "null storeDataReaders?"); Debug.Assert(columnMap != null, "null columnMap?"); Debug.Assert(workspace != null, "null workspace?"); System.Data.Common.QueryCache.QueryCacheManager cacheManager = workspace.GetQueryCacheManager(); const System.Data.Objects.MergeOption NoTracking = System.Data.Objects.MergeOption.NoTracking; ShaperFactory shaperFactory = Translator.TranslateColumnMap (cacheManager, columnMap, workspace, null, NoTracking, true); Shaper recordShaper = shaperFactory.Create(storeDataReader, null, workspace, System.Data.Objects.MergeOption.NoTracking, true); DbDataReader result = new BridgeDataReader(recordShaper, recordShaper.RootCoordinator.TypedCoordinatorFactory, 0); return result; } #endregion #region helpers /// /// Implicitly close this (nested) data reader; will be called whenever /// the user has done a GetValue() or a Read() on a parent reader/record /// to ensure that we consume all our results. We do that because we /// our design requires us to be positioned at the next nested reader's /// first row. /// internal void CloseImplicitly() { Consume(); DataRecord.CloseImplicitly(); } ////// Reads to the end of the source enumerator provided /// private void Consume() { while (ReadInternal()) ; } ////// Figure out the CLR type from the TypeMetadata object; For scalars, /// we can get this from the metadata workspace, but for the rest, we /// just guess at "Object". You need to use the DataRecordInfo property /// to get better information for those. /// /// ///internal static Type GetClrTypeFromTypeMetadata(TypeUsage typeUsage) { Type result; PrimitiveType primitiveType; if (TypeHelpers.TryGetEdmType (typeUsage, out primitiveType)) { result = primitiveType.ClrEquivalentType; } else { if (TypeSemantics.IsReferenceType(typeUsage)) { result = typeof(EntityKey); } else if (TypeUtils.IsStructuredType(typeUsage)) { result = typeof(DbDataRecord); } else if (TypeUtils.IsCollectionType(typeUsage)) { result = typeof(DbDataReader); } else { result = typeof(object); } } return result; } #endregion #region data reader specific properties and methods /// /// implementation for DbDataReader.Depth property /// override public int Depth { get { AssertReaderIsOpen("Depth"); return DataRecord.Depth; } } ////// implementation for DbDataReader.HasRows property /// override public bool HasRows { get { AssertReaderIsOpen("HasRows"); return _hasRows; } } ////// implementation for DbDataReader.IsClosed property /// override public bool IsClosed { get { // Rather that try and track this in two places; we just delegate // to the data record that we constructed; it has more reasons to // have to know this than we do in the data reader. (Of course, // we look at our own closed state too...) return ((_isClosed) || DataRecord.IsClosed); } } ////// implementation for DbDataReader.RecordsAffected property /// override public int RecordsAffected { get { int result = -1; // For nested readers, return -1 which is the default for queries. // We defer to the store reader for rows affected count. Note that for queries, // the provider is generally expected to return -1. // if (DataRecord.Depth == 0) { result = Shaper.Reader.RecordsAffected; } return result; } } ////// Ensures that the reader is actually open, and throws an exception if not /// private void AssertReaderIsOpen(string methodName) { if (IsClosed) { if (DataRecord.IsImplicitlyClosed) { throw EntityUtil.ImplicitlyClosedDataReaderError(); } if (DataRecord.IsExplicitlyClosed) { throw EntityUtil.DataReaderClosed(methodName); } } } ////// implementation for DbDataReader.Close() method /// override public void Close() { // Make sure we explicitly closed the data record, since that's what // where using to track closed state. DataRecord.CloseExplicitly(); if (!_isClosed) { _isClosed = true; if (0 == DataRecord.Depth) { // If we're the root collection, we want to ensure the remainder of // the result column hierarchy is closed out, to avoid dangling // references to it, should it be reused. We also want to physically // close out the source reader as well. Shaper.Reader.Close(); } else { // For non-root collections, we have to consume all the data, or we'll // not be positioned propertly for what comes afterward. Consume(); } } } ////// implementation for DbDataReader.GetEnumerator() method /// [EditorBrowsableAttribute(EditorBrowsableState.Never)] override public IEnumerator GetEnumerator() { IEnumerator result = new DbEnumerator((IDataReader)this, true); // We always want to close the reader; return result; } ////// implementation for DbDataReader.GetSchemaTable() method /// /// This is awaiting some common code /// ////// GetSchemaTable is not supported at this time override public DataTable GetSchemaTable() { throw EntityUtil.NotSupported(System.Data.Entity.Strings.ADP_GetSchemaTableIsNotSupported); } ////// implementation for DbDataReader.NextResult() method /// /// since the bridge currently doesn't support multiple results in a /// single command, this always returns false. /// ///override public bool NextResult() { AssertReaderIsOpen("NextResult"); // Consume results in the source collection to ensure that the // store reader and the bridge data reader are in the same state. // If we are not a root reader, we do not 'own' the store reader // and do nothing. if (0 == DataRecord.Depth) { // NOTE:: this is required to ensure that output parameter values // are set in SQL Server, and other providers where they come after // the results. CommandHelper.ConsumeReader(Shaper.Reader); } else { // For nested readers, make sure we're positioned properly for // the following columns... Consume(); } // SQLBUDT #631726 - ensure we close the records that may be // outstanding... // SQLBUDT #632494 - do this after we consume the underlying reader // so we don't run result assembly through it... CloseImplicitly(); // Reset any state on our attached data record, since we've now // gone past the end of the reader. DataRecord.SetRecordSource(null, false); // NOTE: if the bridge ever supports multiple results in a single // command, we'll need to change this, but for now we can't // ever have another result. return false; } /// /// implementation for DbDataReader.Read() method /// ///override public bool Read() { AssertReaderIsOpen("Read"); // First of all we need to inform each of the nested records that // have been returned that they're "implicitly" closed -- that is // we've moved on. This will also ensure that any records remaining // in any active nested readers are consumed DataRecord.CloseImplicitly(); // OK, now go ahead and advance the source enumerator and set the // record source up bool result = ReadInternal(); DataRecord.SetRecordSource(Shaper.RootEnumerator.Current, result); return result; } /// /// Internal read method; does the work of advancing the root enumerator /// as needed and determining whether it's current record is for our /// coordinator. The public Read method does the assertions and such that /// we don't want to do when we're called from internal methods to do things /// like consume the rest of the reader's contents. /// /// ///private bool ReadInternal() { bool result = false; // If there's nothing waiting for the root enumerator, then attempt // to advance it. if (!Shaper.DataWaiting) { Shaper.DataWaiting = Shaper.RootEnumerator.MoveNext(); } // If we have some data (we may have just read it above) then figure // out who it belongs to-- us or someone else. We also skip over any // records that are for our children (nested readers); if we're being // asked to read, it's too late for them to read them. while (Shaper.DataWaiting && Shaper.RootEnumerator.Current.CoordinatorFactory != CoordinatorFactory && Shaper.RootEnumerator.Current.CoordinatorFactory.Depth > CoordinatorFactory.Depth) { Shaper.DataWaiting = Shaper.RootEnumerator.MoveNext(); } if (Shaper.DataWaiting) { // We found something, go ahead and indicate to the shaper we want // this record, set up the data record, etc. if (Shaper.RootEnumerator.Current.CoordinatorFactory == CoordinatorFactory) { Shaper.DataWaiting = false; Shaper.RootEnumerator.Current.AcceptPendingValues(); result = true; } } return result; } #endregion #region metadata properties and methods /// /// implementation for DbDataReader.DataRecordInfo property /// public DataRecordInfo DataRecordInfo { get { AssertReaderIsOpen("DataRecordInfo"); DataRecordInfo result; if (DataRecord.HasData) { result = DataRecord.DataRecordInfo; } else { result = DefaultRecordState.DataRecordInfo; } return result; } } ////// implementation for DbDataReader.FieldCount property /// override public int FieldCount { get { AssertReaderIsOpen("FieldCount"); // In this method, we need to return a constant value, regardless // of how polymorphic the result is, because there is a lot of code // in the wild that expects it to be constant; Ideally, we'd return // the number of columns in the actual type that we have, but since // that would probably break folks, I'm leaving it at returning the // base set of columns that all rows will have. int result = DefaultRecordState.ColumnCount; return result; } } ////// implementation for DbDataReader.GetDataTypeName() method /// /// ///override public string GetDataTypeName(int ordinal) { AssertReaderIsOpen("GetDataTypeName"); string result; if (DataRecord.HasData) { result = DataRecord.GetDataTypeName(ordinal); } else { result = TypeHelpers.GetFullName(DefaultRecordState.GetTypeUsage(ordinal)); } return result; } /// /// implementation for DbDataReader.GetFieldType() method /// /// ///override public Type GetFieldType(int ordinal) { AssertReaderIsOpen("GetFieldType"); Type result; if (DataRecord.HasData) { result = DataRecord.GetFieldType(ordinal); } else { result = GetClrTypeFromTypeMetadata(DefaultRecordState.GetTypeUsage(ordinal)); } return result; } /// /// implementation for DbDataReader.GetName() method /// /// ///override public string GetName(int ordinal) { AssertReaderIsOpen("GetName"); string result; if (DataRecord.HasData) { result = DataRecord.GetName(ordinal); } else { result = DefaultRecordState.GetName(ordinal); } return result; } /// /// implementation for DbDataReader.GetOrdinal() method /// /// ///override public int GetOrdinal(string name) { AssertReaderIsOpen("GetOrdinal"); int result; if (DataRecord.HasData) { result = DataRecord.GetOrdinal(name); } else { result = DefaultRecordState.GetOrdinal(name); } return result; } /// /// implementation for DbDataReader.GetProviderSpecificFieldType() method /// /// ////// GetProviderSpecificFieldType is not supported at this time [EditorBrowsableAttribute(EditorBrowsableState.Never)] override public Type GetProviderSpecificFieldType(int ordinal) { throw EntityUtil.NotSupported(); } #endregion #region data record properties and methods //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // // The remaining methods on this class delegate to the inner data record // //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// #region general getter methods and indexer properties ////// implementation for DbDataReader[ordinal] indexer value getter /// override public object this[int ordinal] { get { return DataRecord[ordinal]; } } ////// implementation for DbDataReader[name] indexer value getter /// override public object this[string name] { get { int ordinal = GetOrdinal(name); return DataRecord[ordinal]; } } ////// implementation for DbDataReader.GetProviderSpecificValue() method /// /// ////// GetProviderSpecificValue is not supported at this time [EditorBrowsableAttribute(EditorBrowsableState.Never)] public override object GetProviderSpecificValue(int ordinal) { throw EntityUtil.NotSupported(); } ////// implementation for DbDataReader.GetProviderSpecificValues() method /// /// ////// GetProviderSpecificValues is not supported at this time [EditorBrowsableAttribute(EditorBrowsableState.Never)] public override int GetProviderSpecificValues(object[] values) { throw EntityUtil.NotSupported(); } ////// implementation for DbDataReader.GetValue() method /// /// ///override public Object GetValue(int ordinal) { return DataRecord.GetValue(ordinal); } /// /// implementation for DbDataReader.GetValues() method /// /// ///override public int GetValues(object[] values) { return DataRecord.GetValues(values); } #endregion #region simple scalar value getter methods /// /// implementation for DbDataReader.GetBoolean() method /// /// ///override public bool GetBoolean(int ordinal) { return DataRecord.GetBoolean(ordinal); } /// /// implementation for DbDataReader.GetByte() method /// /// ///override public byte GetByte(int ordinal) { return DataRecord.GetByte(ordinal); } /// /// implementation for DbDataReader.GetChar() method /// /// ///override public char GetChar(int ordinal) { return DataRecord.GetChar(ordinal); } /// /// implementation for DbDataReader.GetDateTime() method /// /// ///override public DateTime GetDateTime(int ordinal) { return DataRecord.GetDateTime(ordinal); } /// /// implementation for DbDataReader.GetDecimal() method /// /// ///override public Decimal GetDecimal(int ordinal) { return DataRecord.GetDecimal(ordinal); } /// /// implementation for DbDataReader.GetDouble() method /// /// ///override public double GetDouble(int ordinal) { return DataRecord.GetDouble(ordinal); } /// /// implementation for DbDataReader.GetFloat() method /// /// ///override public float GetFloat(int ordinal) { return DataRecord.GetFloat(ordinal); } /// /// implementation for DbDataReader.GetGuid() method /// /// ///override public Guid GetGuid(int ordinal) { return DataRecord.GetGuid(ordinal); } /// /// implementation for DbDataReader.GetInt16() method /// /// ///override public Int16 GetInt16(int ordinal) { return DataRecord.GetInt16(ordinal); } /// /// implementation for DbDataReader.GetInt32() method /// /// ///override public Int32 GetInt32(int ordinal) { return DataRecord.GetInt32(ordinal); } /// /// implementation for DbDataReader.GetInt64() method /// /// ///override public Int64 GetInt64(int ordinal) { return DataRecord.GetInt64(ordinal); } /// /// implementation for DbDataReader.GetString() method /// /// ///override public String GetString(int ordinal) { return DataRecord.GetString(ordinal); } /// /// implementation for DbDataReader.IsDBNull() method /// /// ///override public bool IsDBNull(int ordinal) { return DataRecord.IsDBNull(ordinal); } #endregion #region chunking scalar value getter methods /// /// implementation for DbDataReader.GetBytes() method /// /// /// /// /// /// ///override public long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length) { return DataRecord.GetBytes(ordinal, dataOffset, buffer, bufferOffset, length); } /// /// implementation for DbDataReader.GetChars() method /// /// /// /// /// /// ///override public long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length) { return DataRecord.GetChars(ordinal, dataOffset, buffer, bufferOffset, length); } #endregion #region complex type getters /// /// implementation for DbDataReader.GetData() method /// /// ///override protected DbDataReader GetDbDataReader(int ordinal) { return (DbDataReader)DataRecord.GetData(ordinal); } /// /// implementation for DbDataReader.GetDataRecord() method /// /// ///public DbDataRecord GetDataRecord(int ordinal) { return DataRecord.GetDataRecord(ordinal); } /// /// Used to return a nested result /// /// ///public DbDataReader GetDataReader(int ordinal) { return this.GetDbDataReader(ordinal); } #endregion #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DefaultPrintController.cs
- SimpleTypeResolver.cs
- GPPOINT.cs
- XamlToRtfWriter.cs
- DataGridViewCellConverter.cs
- WorkflowCreationContext.cs
- ParseChildrenAsPropertiesAttribute.cs
- IisTraceListener.cs
- DataAdapter.cs
- AddIn.cs
- ElementUtil.cs
- DataGridViewCellParsingEventArgs.cs
- WmlValidatorAdapter.cs
- SignatureHelper.cs
- MLangCodePageEncoding.cs
- listitem.cs
- ToReply.cs
- MachineKeyValidationConverter.cs
- WindowProviderWrapper.cs
- ObjectRef.cs
- WebPartConnectionsCloseVerb.cs
- DataRowCollection.cs
- ViewCellRelation.cs
- ProviderConnectionPointCollection.cs
- ThreadStartException.cs
- GlobalProxySelection.cs
- Double.cs
- XmlDataSourceNodeDescriptor.cs
- SystemUnicastIPAddressInformation.cs
- TreeNodeConverter.cs
- WebPartUtil.cs
- SchemaDeclBase.cs
- Error.cs
- CodeStatementCollection.cs
- FontSizeConverter.cs
- XMLSyntaxException.cs
- TimeSpan.cs
- AuthenticationService.cs
- _CacheStreams.cs
- QueryRewriter.cs
- OptimizedTemplateContent.cs
- MessageBox.cs
- InheritanceAttribute.cs
- NativeObjectSecurity.cs
- LabelDesigner.cs
- HtmlTable.cs
- HttpFileCollection.cs
- BinaryExpression.cs
- ErrorHandler.cs
- MessageUtil.cs
- UpdateCommand.cs
- MethodToken.cs
- BitmapFrameEncode.cs
- fixedPageContentExtractor.cs
- TextParagraph.cs
- CrossSiteScriptingValidation.cs
- BasicBrowserDialog.designer.cs
- RuntimeResourceSet.cs
- TreeNodeCollection.cs
- IPGlobalProperties.cs
- TextBlockAutomationPeer.cs
- Vars.cs
- BooleanFacetDescriptionElement.cs
- NavigationProperty.cs
- CachedBitmap.cs
- _OSSOCK.cs
- ProxyManager.cs
- ScriptDescriptor.cs
- DeobfuscatingStream.cs
- IpcServerChannel.cs
- Knowncolors.cs
- NTAccount.cs
- Effect.cs
- ToolStripRendererSwitcher.cs
- HttpFileCollection.cs
- HwndStylusInputProvider.cs
- messageonlyhwndwrapper.cs
- SQLSingleStorage.cs
- GridSplitter.cs
- GenericAuthenticationEventArgs.cs
- NavigationPropertySingletonExpression.cs
- TimeZone.cs
- SimpleRecyclingCache.cs
- TypeSemantics.cs
- Selection.cs
- ToolBarPanel.cs
- NotificationContext.cs
- PrintDialog.cs
- EncodingStreamWrapper.cs
- ExceptionHelpers.cs
- UseLicense.cs
- PipelineModuleStepContainer.cs
- ExclusiveHandle.cs
- StaticFileHandler.cs
- LayoutSettings.cs
- ContentElement.cs
- TextTreeTextBlock.cs
- MonthCalendar.cs
- DrawingGroup.cs
- CodeMethodReturnStatement.cs