Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / Data / System / Data / ProviderBase / SchemaMapping.cs / 1 / SchemaMapping.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Data.ProviderBase { using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Diagnostics; using System.Globalization; sealed internal class SchemaMapping { // DataColumns match in length and name order as the DataReader, no chapters private const int MapExactMatch = 0; // DataColumns has different length, but correct name order as the DataReader, no chapters private const int MapDifferentSize = 1; // DataColumns may have different length, but a differant name ordering as the DataReader, no chapters private const int MapReorderedValues = 2; // DataColumns may have different length, but correct name order as the DataReader, with chapters private const int MapChapters = 3; // DataColumns may have different length, but a differant name ordering as the DataReader, with chapters private const int MapChaptersReordered = 4; // map xml string data to DataColumn with DataType=typeof(SqlXml) private const int SqlXml = 1; // map xml string data to DataColumn with DataType=typeof(XmlDocument) private const int XmlDocument = 2; private readonly DataSet _dataSet; // the current dataset, may be null if we are only filling a DataTable private DataTable _dataTable; // the current DataTable, should never be null private readonly DataAdapter _adapter; private readonly DataReaderContainer _dataReader; private readonly DataTable _schemaTable; // will be null if Fill without schema private readonly DataTableMapping _tableMapping; // unique (generated) names based from DataReader.GetName(i) private readonly string[] _fieldNames; private readonly object[] _readerDataValues; private object[] _mappedDataValues; // array passed to dataRow.AddUpdate(), if needed private int[] _indexMap; // index map that maps dataValues -> _mappedDataValues, if needed private bool[] _chapterMap; // which DataReader indexes have chapters private int[] _xmlMap; // map which value in _readerDataValues to convert to a Xml datatype, (SqlXml/XmlDocument) private int _mappedMode; // modes as described as above private int _mappedLength; private readonly LoadOption _loadOption; internal SchemaMapping(DataAdapter adapter, DataSet dataset, DataTable datatable, DataReaderContainer dataReader, bool keyInfo, SchemaType schemaType, string sourceTableName, bool gettingData, DataColumn parentChapterColumn, object parentChapterValue) { Debug.Assert(null != adapter, "adapter"); Debug.Assert(null != dataReader, "dataReader"); Debug.Assert(0 < dataReader.FieldCount, "FieldCount"); Debug.Assert(null != dataset || null != datatable, "SchemaMapping - null dataSet"); Debug.Assert(SchemaType.Mapped == schemaType || SchemaType.Source == schemaType, "SetupSchema - invalid schemaType"); _dataSet = dataset; // setting DataSet implies chapters are supported _dataTable = datatable; // setting only DataTable, not DataSet implies chapters are not supported _adapter = adapter; _dataReader = dataReader; if (keyInfo) { _schemaTable = dataReader.GetSchemaTable(); } if (adapter.ShouldSerializeFillLoadOption()) { _loadOption = adapter.FillLoadOption; } else if (adapter.AcceptChangesDuringFill) { _loadOption = (LoadOption)4; // true } else { _loadOption = (LoadOption)5; //false } MissingMappingAction mappingAction; MissingSchemaAction schemaAction; if (SchemaType.Mapped == schemaType) { mappingAction = _adapter.MissingMappingAction; schemaAction = _adapter.MissingSchemaAction; if (!ADP.IsEmpty(sourceTableName)) { // MDAC 66034 _tableMapping = _adapter.GetTableMappingBySchemaAction(sourceTableName, sourceTableName, mappingAction); } else if (null != _dataTable) { int index = _adapter.IndexOfDataSetTable(_dataTable.TableName); if (-1 != index) { _tableMapping = _adapter.TableMappings[index]; } else { switch (mappingAction) { case MissingMappingAction.Passthrough: _tableMapping = new DataTableMapping(_dataTable.TableName, _dataTable.TableName); break; case MissingMappingAction.Ignore: _tableMapping = null; break; case MissingMappingAction.Error: throw ADP.MissingTableMappingDestination(_dataTable.TableName); default: throw ADP.InvalidMissingMappingAction(mappingAction); } } } } else if (SchemaType.Source == schemaType) { mappingAction = System.Data.MissingMappingAction.Passthrough; schemaAction = Data.MissingSchemaAction.Add; if (!ADP.IsEmpty(sourceTableName)) { // MDAC 66034 _tableMapping = DataTableMappingCollection.GetTableMappingBySchemaAction(null, sourceTableName, sourceTableName, mappingAction); } else if (null != _dataTable) { int index = _adapter.IndexOfDataSetTable(_dataTable.TableName); // MDAC 66034 if (-1 != index) { _tableMapping = _adapter.TableMappings[index]; } else { _tableMapping = new DataTableMapping(_dataTable.TableName, _dataTable.TableName); } } } else { throw ADP.InvalidSchemaType(schemaType); } if (null != _tableMapping) { if (null == _dataTable) { _dataTable = _tableMapping.GetDataTableBySchemaAction(_dataSet, schemaAction); } if (null != _dataTable) { _fieldNames = GenerateFieldNames(dataReader); if (null == _schemaTable) { _readerDataValues = SetupSchemaWithoutKeyInfo(mappingAction, schemaAction, gettingData, parentChapterColumn, parentChapterValue); } else { _readerDataValues = SetupSchemaWithKeyInfo(mappingAction, schemaAction, gettingData, parentChapterColumn, parentChapterValue); } } // else (null == _dataTable) which means ignore (mapped to nothing) } } internal DataReaderContainer DataReader { get { return _dataReader; } } internal DataTable DataTable { get { return _dataTable; } } internal object[] DataValues { get { return _readerDataValues; } } internal void ApplyToDataRow(DataRow dataRow) { DataColumnCollection columns = dataRow.Table.Columns; _dataReader.GetValues(_readerDataValues); object[] mapped = GetMappedValues(); bool[] readOnly = new bool[mapped.Length]; for (int i = 0; i < readOnly.Length; ++i) { readOnly[i] = columns[i].ReadOnly; } try { try { // allow all columns to be written to for (int i = 0; i < readOnly.Length; ++i) { if (0 == columns[i].Expression.Length) { // WebData 110773 columns[i].ReadOnly = false; } } for(int i = 0; i < mapped.Length; ++i) { if (null != mapped[i]) { // MDAC 72659 dataRow[i] = mapped[i]; } } } finally { // ReadOnly // reset readonly flag on all columns for (int i = 0; i < readOnly.Length; ++i) { if (0 == columns[i].Expression.Length) { // WebData 110773 columns[i].ReadOnly = readOnly[i]; } } } } finally { // FreeDataRowChapters if (null != _chapterMap) { FreeDataRowChapters(); } } } private void MappedChapterIndex() { // mode 4 int length = _mappedLength; for (int i = 0; i < length; i++) { int k = _indexMap[i]; if (0 <= k) { _mappedDataValues[k] = _readerDataValues[i]; // from reader to dataset if (_chapterMap[i]) { _mappedDataValues[k] = null; // InvalidCast from DataReader to AutoIncrement DataColumn } } } } private void MappedChapter() { // mode 3 int length = _mappedLength; for (int i = 0; i < length; i++) { _mappedDataValues[i] = _readerDataValues[i]; // from reader to dataset if (_chapterMap[i]) { _mappedDataValues[i] = null; // InvalidCast from DataReader to AutoIncrement DataColumn } } } private void MappedIndex() { // mode 2 Debug.Assert(_mappedLength == _indexMap.Length, "incorrect precomputed length"); int length = _mappedLength; for (int i = 0; i < length; i++) { int k = _indexMap[i]; if (0 <= k) { _mappedDataValues[k] = _readerDataValues[i]; // from reader to dataset } } } private void MappedValues() { // mode 1 Debug.Assert(_mappedLength == Math.Min(_readerDataValues.Length, _mappedDataValues.Length), "incorrect precomputed length"); int length = _mappedLength; for (int i = 0; i < length; ++i) { _mappedDataValues[i] = _readerDataValues[i]; // from reader to dataset }; } private object[] GetMappedValues() { // mode 0 if (null != _xmlMap) { for(int i = 0; i < _xmlMap.Length; ++i) { if (0 != _xmlMap[i]) { // get the string/SqlString xml value string xml = _readerDataValues[i] as string; if ((null == xml) && (_readerDataValues[i] is System.Data.SqlTypes.SqlString)) { System.Data.SqlTypes.SqlString x = (System.Data.SqlTypes.SqlString)_readerDataValues[i]; if (!x.IsNull) { xml = x.Value; } else { switch(_xmlMap[i]) { case SqlXml: // map strongly typed SqlString.Null to SqlXml.Null _readerDataValues[i] = System.Data.SqlTypes.SqlXml.Null; break; default: _readerDataValues[i] = DBNull.Value; break; } } } if (null != xml) { switch(_xmlMap[i]) { case SqlXml: // turn string into a SqlXml value for DataColumn System.Xml.XmlReaderSettings settings = new System.Xml.XmlReaderSettings(); settings.ConformanceLevel = System.Xml.ConformanceLevel.Fragment; System.Xml.XmlReader reader = System.Xml.XmlReader.Create(new System.IO.StringReader(xml), settings, (string)null); _readerDataValues[i] = new System.Data.SqlTypes.SqlXml(reader); break; case XmlDocument: // turn string into XmlDocument value for DataColumn System.Xml.XmlDocument document = new System.Xml.XmlDocument(); document.LoadXml(xml); _readerDataValues[i] = document; break; } // default: let value fallthrough to DataSet which may fail with ArgumentException } } } } switch(_mappedMode) { default: case MapExactMatch: Debug.Assert(0 == _mappedMode, "incorrect mappedMode"); Debug.Assert((null == _chapterMap) && (null == _indexMap) && (null == _mappedDataValues), "incorrect MappedValues"); return _readerDataValues; // from reader to dataset case MapDifferentSize: Debug.Assert((null == _chapterMap) && (null == _indexMap) && (null != _mappedDataValues), "incorrect MappedValues"); MappedValues(); break; case MapReorderedValues: Debug.Assert((null == _chapterMap) && (null != _indexMap) && (null != _mappedDataValues), "incorrect MappedValues"); MappedIndex(); break; case MapChapters: Debug.Assert((null != _chapterMap) && (null == _indexMap) && (null != _mappedDataValues), "incorrect MappedValues"); MappedChapter(); break; case MapChaptersReordered: Debug.Assert((null != _chapterMap) && (null != _indexMap) && (null != _mappedDataValues), "incorrect MappedValues"); MappedChapterIndex(); break; } return _mappedDataValues; } internal void LoadDataRowWithClear() { // for FillErrorEvent to ensure no values leftover from previous row for (int i = 0; i < _readerDataValues.Length; ++i) { _readerDataValues[i] = null; } LoadDataRow(); } internal void LoadDataRow() { try { _dataReader.GetValues(_readerDataValues); object[] mapped = GetMappedValues(); DataRow dataRow; switch(_loadOption) { case LoadOption.OverwriteChanges: case LoadOption.PreserveChanges: case LoadOption.Upsert: dataRow = _dataTable.LoadDataRow(mapped, _loadOption); break; case (LoadOption)4: // true dataRow = _dataTable.LoadDataRow(mapped, true); break; case (LoadOption)5: // false dataRow = _dataTable.LoadDataRow(mapped, false); break; default: Debug.Assert(false, "unexpected LoadOption"); throw ADP.InvalidLoadOption(_loadOption); } if ((null != _chapterMap) && (null != _dataSet)) { LoadDataRowChapters(dataRow); // MDAC 70772 } } finally { if (null != _chapterMap) { FreeDataRowChapters(); // MDAC 71900 } } } private void FreeDataRowChapters() { for(int i = 0; i < _chapterMap.Length; ++i) { if (_chapterMap[i]) { IDisposable disposable = (_readerDataValues[i] as IDisposable); if (null != disposable) { _readerDataValues[i] = null; disposable.Dispose(); } } } } internal int LoadDataRowChapters(DataRow dataRow) { int datarowadded = 0; int rowLength = _chapterMap.Length; for(int i = 0; i < rowLength; ++i) { if (_chapterMap[i]) { object readerValue = _readerDataValues[i]; if ((null != readerValue) && !Convert.IsDBNull(readerValue)) { // MDAC 70441 _readerDataValues[i] = null; using (IDataReader nestedReader = (IDataReader) readerValue) { if (!nestedReader.IsClosed) { Debug.Assert(null != _dataSet, "if chapters, then Fill(DataSet,...) not Fill(DataTable,...)"); object parentChapterValue; DataColumn parentChapterColumn; if (null == _indexMap) { parentChapterColumn = _dataTable.Columns[i]; parentChapterValue = dataRow[parentChapterColumn]; } else { parentChapterColumn = _dataTable.Columns[_indexMap[i]]; parentChapterValue = dataRow[parentChapterColumn]; } // correct on Fill, not FillFromReader string chapterTableName = _tableMapping.SourceTable + _fieldNames[i]; // MDAC 70908 DataReaderContainer readerHandler = DataReaderContainer.Create(nestedReader, _dataReader.ReturnProviderSpecificTypes); datarowadded += _adapter.FillFromReader(_dataSet, null, chapterTableName, readerHandler, 0, 0, parentChapterColumn, parentChapterValue); } } } } } return datarowadded; } private int[] CreateIndexMap(int count, int index) { int[] values = new int[count]; for (int i = 0; i < index; ++i) { values[i] = i; } return values; } private static string[] GenerateFieldNames(DataReaderContainer dataReader) { string[] fieldNames = new string[dataReader.FieldCount]; for(int i = 0; i < fieldNames.Length; ++i) { fieldNames[i] = dataReader.GetName(i); } ADP.BuildSchemaTableInfoTableNames(fieldNames); return fieldNames; } private DataColumn[] ResizeColumnArray(DataColumn[] rgcol, int len) { Debug.Assert(rgcol != null, "invalid call to ResizeArray"); Debug.Assert(len <= rgcol.Length, "invalid len passed to ResizeArray"); DataColumn[] tmp = new DataColumn[len]; Array.Copy(rgcol, tmp, len); return tmp; } private void AddItemToAllowRollback(ref List
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataGridViewCellConverter.cs
- ToggleProviderWrapper.cs
- PolicyStatement.cs
- RealProxy.cs
- TimelineCollection.cs
- BmpBitmapDecoder.cs
- TextEditorParagraphs.cs
- IndependentlyAnimatedPropertyMetadata.cs
- RelationshipConstraintValidator.cs
- WebEventTraceProvider.cs
- CollectionsUtil.cs
- ClientProxyGenerator.cs
- HtmlTextArea.cs
- DomainUpDown.cs
- MemberInfoSerializationHolder.cs
- PassportIdentity.cs
- EntryPointNotFoundException.cs
- DataTable.cs
- tooltip.cs
- PartitionedStreamMerger.cs
- PackWebResponse.cs
- OpenFileDialog.cs
- RelatedView.cs
- DbProviderSpecificTypePropertyAttribute.cs
- HtmlWindow.cs
- latinshape.cs
- RequestDescription.cs
- ScaleTransform3D.cs
- TracePayload.cs
- SqlCommand.cs
- _NegoState.cs
- Substitution.cs
- ToolZone.cs
- XmlCollation.cs
- PropertyValueChangedEvent.cs
- InvokeMethod.cs
- GridViewDeleteEventArgs.cs
- UncommonField.cs
- CheckBox.cs
- ACE.cs
- TaskScheduler.cs
- BinaryMessageEncodingElement.cs
- SafeBitVector32.cs
- securestring.cs
- ProgressiveCrcCalculatingStream.cs
- WS2007HttpBinding.cs
- EventEntry.cs
- ListSortDescriptionCollection.cs
- CompoundFileDeflateTransform.cs
- SqlInternalConnectionSmi.cs
- SystemColors.cs
- lengthconverter.cs
- StringInfo.cs
- BitStack.cs
- ObjectIDGenerator.cs
- DataObjectCopyingEventArgs.cs
- ViewSimplifier.cs
- VolatileResourceManager.cs
- RenameRuleObjectDialog.Designer.cs
- FreeIndexList.cs
- X509ChainElement.cs
- XPathNodeHelper.cs
- FileUtil.cs
- TextSelectionProcessor.cs
- Module.cs
- SelectionHighlightInfo.cs
- NotifyParentPropertyAttribute.cs
- PrimitiveDataContract.cs
- DataGridTextBoxColumn.cs
- SelectionWordBreaker.cs
- PropertyDescriptorComparer.cs
- BitVector32.cs
- XmlSchemaAnnotation.cs
- EdmValidator.cs
- TransportReplyChannelAcceptor.cs
- VirtualPathData.cs
- OptimalTextSource.cs
- ServiceContractListItemList.cs
- ContentControl.cs
- ComplexBindingPropertiesAttribute.cs
- StreamMarshaler.cs
- LifetimeServices.cs
- EventLogPermission.cs
- EdmComplexPropertyAttribute.cs
- ConfigurationStrings.cs
- SafeCoTaskMem.cs
- SchemaImporterExtension.cs
- TaskFileService.cs
- DefaultAuthorizationContext.cs
- ObjectConverter.cs
- RegexStringValidatorAttribute.cs
- Binding.cs
- XmlFormatExtensionAttribute.cs
- QuotedPrintableStream.cs
- FixedFindEngine.cs
- Subset.cs
- EventWaitHandle.cs
- TypeTypeConverter.cs
- MediaScriptCommandRoutedEventArgs.cs
- NotFiniteNumberException.cs