Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Data / System / Data / ProviderBase / SchemaMapping.cs / 1305376 / 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
- ListItem.cs
- ReadOnlyPropertyMetadata.cs
- ToolStripItemRenderEventArgs.cs
- MissingMemberException.cs
- ProgressChangedEventArgs.cs
- UrlAuthorizationModule.cs
- DataGridViewRowsRemovedEventArgs.cs
- WebDisplayNameAttribute.cs
- SourceFilter.cs
- ItemsChangedEventArgs.cs
- NameSpaceExtractor.cs
- UnionCqlBlock.cs
- SqlConnectionString.cs
- CmsInterop.cs
- StrokeCollectionDefaultValueFactory.cs
- TypeContext.cs
- XmlSchemaException.cs
- DataGridViewSelectedCellCollection.cs
- EntityDesignerUtils.cs
- MexTcpBindingElement.cs
- __ComObject.cs
- SafeNativeMethodsCLR.cs
- HtmlControlPersistable.cs
- OdbcTransaction.cs
- DataGridViewCellConverter.cs
- ToolboxComponentsCreatedEventArgs.cs
- DataServiceExpressionVisitor.cs
- OperandQuery.cs
- SymbolType.cs
- ChannelFactoryBase.cs
- IteratorFilter.cs
- AttributeQuery.cs
- TraceShell.cs
- WebBrowserSiteBase.cs
- AsyncPostBackErrorEventArgs.cs
- ComboBoxItem.cs
- UInt32.cs
- EventLogPermissionAttribute.cs
- SecurityToken.cs
- OuterGlowBitmapEffect.cs
- RootBrowserWindowAutomationPeer.cs
- DbConnectionStringCommon.cs
- EventProxy.cs
- SelectionHighlightInfo.cs
- HostProtectionException.cs
- StrokeCollection2.cs
- GiveFeedbackEvent.cs
- XmlNode.cs
- SqlDataSourceCustomCommandEditor.cs
- Typography.cs
- DisposableCollectionWrapper.cs
- XmlObjectSerializerWriteContextComplexJson.cs
- ResourcePermissionBaseEntry.cs
- XamlClipboardData.cs
- TreeNodeCollection.cs
- GregorianCalendarHelper.cs
- BaseResourcesBuildProvider.cs
- SecurityStandardsManager.cs
- SafeBitVector32.cs
- UiaCoreApi.cs
- TextFormatter.cs
- IMembershipProvider.cs
- MimeTypePropertyAttribute.cs
- Lease.cs
- HttpResponse.cs
- ToolStripComboBox.cs
- MetaModel.cs
- TrimSurroundingWhitespaceAttribute.cs
- DesignerDataColumn.cs
- Pkcs7Signer.cs
- PrintDialog.cs
- WeakRefEnumerator.cs
- ReadOnlyHierarchicalDataSource.cs
- TextTreeNode.cs
- brushes.cs
- CompilerParameters.cs
- TextRangeProviderWrapper.cs
- InspectionWorker.cs
- IOThreadScheduler.cs
- NameValuePermission.cs
- ToolStripSplitButton.cs
- EditableRegion.cs
- BamlRecordHelper.cs
- NameTable.cs
- SqlCacheDependencyDatabaseCollection.cs
- Axis.cs
- EventSinkHelperWriter.cs
- CompositeControl.cs
- PackageRelationshipSelector.cs
- Merger.cs
- PersonalizationProviderCollection.cs
- BaseParagraph.cs
- Int32Storage.cs
- Model3D.cs
- UpdateTranslator.cs
- ClientEventManager.cs
- MenuStrip.cs
- BrowserCapabilitiesCodeGenerator.cs
- MachineKeySection.cs
- RegionIterator.cs