/// <summary> /// Move the PendingValues to the CurrentValues for this record and all nested /// records. We keep the pending values separate from the current ones because /// we may have a nested reader in the middle, and while we're reading forward /// on the nested reader we we'll blast over the pending values. /// /// This should be called as part of the data reader's Read() method. /// </summary> internal void AcceptPendingValues() { object[] temp = CurrentColumnValues; CurrentColumnValues = PendingColumnValues; PendingColumnValues = temp; _currentEntityRecordInfo = _pendingEntityRecordInfo; _pendingEntityRecordInfo = null; _currentIsNull = _pendingIsNull; // if (RecordStateFactory.HasNestedColumns) { for (int ordinal = 0; ordinal < CurrentColumnValues.Length; ordinal++) { if (RecordStateFactory.IsColumnNested[ordinal]) { RecordState recordState = CurrentColumnValues[ordinal] as RecordState; if (null != recordState) { recordState.AcceptPendingValues(); } } } } }
/// <summary> /// Should be called after each Read on the data reader. /// </summary> internal void SetRecordSource(RecordState newSource, bool hasData) { Debug.Assert(null == _currentNestedRecord, "didn't close the nested record?"); Debug.Assert(null == _currentNestedReader, "didn't close the nested reader?"); // A peculiar behavior of IEnumerator is that when MoveNext() returns // false, the Current still points to the last value, which is not // what we really want to reflect here. if (hasData) { Debug.Assert(null != newSource, "hasData but null newSource?"); // this shouldn't happen... _source = newSource; } else { _source = null; } _status = Status.Open; _lastColumnRead = -1; _lastDataOffsetRead = -1; _lastOrdinalCheckedForNull = -1; _lastValueCheckedForNull = null; }
private void SetShaper(Shaper<RecordState> shaper, CoordinatorFactory<RecordState> coordinatorFactory, int depth) { _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) { var 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?"); }
/// <summary> /// Called by our parent object to ensure that we're marked as implicitly /// closed; will not be called for root level data readers. /// </summary> internal void CloseImplicitly() { _status = Status.ClosedImplicitly; _source = null; // can't have data any longer once we're closed. CloseNestedObjectImplicitly(); }