Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Data / System / Data / XmlToDatasetMap.cs / 1 / XmlToDatasetMap.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //[....] //----------------------------------------------------------------------------- namespace System.Data { using System; using System.Xml; using System.Collections; using System.Diagnostics; using System.Globalization; // This is an internal helper class used during Xml load to DataSet/DataDocument. // XmlToDatasetMap class provides functionality for binding elemants/atributes // to DataTable / DataColumn internal sealed class XmlToDatasetMap { private sealed class XmlNodeIdentety { public string LocalName; public string NamespaceURI; public XmlNodeIdentety(string localName, string namespaceURI) { this.LocalName = localName; this.NamespaceURI = namespaceURI; } override public int GetHashCode() { return ((object) LocalName).GetHashCode(); } override public bool Equals(object obj) { XmlNodeIdentety id = (XmlNodeIdentety) obj; return ( (String.Compare(this.LocalName, id.LocalName, StringComparison.OrdinalIgnoreCase) == 0) && (String.Compare(this.NamespaceURI, id.NamespaceURI, StringComparison.OrdinalIgnoreCase) == 0) ); } } // This class exist to avoid alocatin of XmlNodeIdentety to every acces to the hash table. // Unfortunetely XmlNode doesn't export single identety object. internal sealed class XmlNodeIdHashtable : Hashtable { private XmlNodeIdentety id = new XmlNodeIdentety(string.Empty, string.Empty); public XmlNodeIdHashtable(Int32 capacity) : base(capacity) {} public object this[XmlNode node] { get { id.LocalName = node.LocalName; id.NamespaceURI = node.NamespaceURI; return this[id]; } } public object this[XmlReader dataReader] { get { id.LocalName = dataReader.LocalName; id.NamespaceURI = dataReader.NamespaceURI; return this[id]; } } public object this[DataTable table] { get { id.LocalName = table.EncodedTableName; id.NamespaceURI = table.Namespace; return this[id]; } } public object this[string name] { get { id.LocalName = name; id.NamespaceURI = String.Empty; return this[id]; } } } private sealed class TableSchemaInfo { public DataTable TableSchema; public XmlNodeIdHashtable ColumnsSchemaMap; public TableSchemaInfo(DataTable tableSchema) { this.TableSchema = tableSchema; this.ColumnsSchemaMap = new XmlNodeIdHashtable(tableSchema.Columns.Count); } } XmlNodeIdHashtable tableSchemaMap; // Holds all the tables information TableSchemaInfo lastTableSchemaInfo = null; // Used to infer schema public XmlToDatasetMap(DataSet dataSet, XmlNameTable nameTable) { Debug.Assert(dataSet != null, "DataSet can't be null"); Debug.Assert(nameTable != null, "NameTable can't be null"); BuildIdentityMap(dataSet, nameTable); } // Used to read data with known schema public XmlToDatasetMap(XmlNameTable nameTable, DataSet dataSet) { Debug.Assert(dataSet != null, "DataSet can't be null"); Debug.Assert(nameTable != null, "NameTable can't be null"); BuildIdentityMap(nameTable, dataSet); } // Used to infer schema public XmlToDatasetMap(DataTable dataTable, XmlNameTable nameTable) { Debug.Assert(dataTable != null, "DataTable can't be null"); Debug.Assert(nameTable != null, "NameTable can't be null"); BuildIdentityMap(dataTable, nameTable); } // Used to read data with known schema public XmlToDatasetMap(XmlNameTable nameTable, DataTable dataTable) { Debug.Assert(dataTable != null, "DataTable can't be null"); Debug.Assert(nameTable != null, "NameTable can't be null"); BuildIdentityMap(nameTable, dataTable); } static internal bool IsMappedColumn(DataColumn c) { return (c.ColumnMapping != MappingType.Hidden); } // Used to infere schema private TableSchemaInfo AddTableSchema(DataTable table, XmlNameTable nameTable) { // [....]: Because in our case reader already read the document all names that we can meet in the // document already has an entry in NameTable. // If in future we will build identity map before reading XML we can replace Get() to Add() // [....]: GetIdentity is called from two places: BuildIdentityMap() and LoadRows() // First case deals with decoded names; Second one with encoded names. // We decided encoded names in first case (instead of decoding them in second) // because it save us time in LoadRows(). We have, as usual, more data them schemas string tableLocalName = nameTable.Get(table.EncodedTableName); string tableNamespace = nameTable.Get(table.Namespace ); if(tableLocalName == null) { // because name of this table isn't present in XML we don't need mapping for it. // Less mapping faster we work. return null; } TableSchemaInfo tableSchemaInfo = new TableSchemaInfo(table); tableSchemaMap[new XmlNodeIdentety(tableLocalName, tableNamespace)] = tableSchemaInfo; return tableSchemaInfo; } private TableSchemaInfo AddTableSchema(XmlNameTable nameTable, DataTable table) { // [....]:This is the opposite of the previous function: // we populate the nametable so that the hash comparison can happen as // object comparison instead of strings. // [....]: GetIdentity is called from two places: BuildIdentityMap() and LoadRows() // First case deals with decoded names; Second one with encoded names. // We decided encoded names in first case (instead of decoding them in second) // because it save us time in LoadRows(). We have, as usual, more data them schemas string _tableLocalName = table.EncodedTableName; // Table name string tableLocalName = nameTable.Get(_tableLocalName); // Look it up in nametable if(tableLocalName == null) { // If not found tableLocalName = nameTable.Add(_tableLocalName); // Add it } table.encodedTableName = tableLocalName; // And set it back string tableNamespace = nameTable.Get(table.Namespace); // Look ip table namespace if (tableNamespace == null) { // If not found tableNamespace = nameTable.Add(table.Namespace); // Add it } else { if (table.tableNamespace != null) // Update table namespace table.tableNamespace = tableNamespace; } TableSchemaInfo tableSchemaInfo = new TableSchemaInfo(table); // Create new table schema info tableSchemaMap[new XmlNodeIdentety(tableLocalName, tableNamespace)] = tableSchemaInfo; // And add it to the hashtable return tableSchemaInfo; // Return it as we have to populate // Column schema map and Child table // schema map in it } private bool AddColumnSchema(DataColumn col, XmlNameTable nameTable, XmlNodeIdHashtable columns) { string columnLocalName = nameTable.Get(col.EncodedColumnName ); string columnNamespace = nameTable.Get(col.Namespace ); if(columnLocalName == null) { return false; } XmlNodeIdentety idColumn = new XmlNodeIdentety(columnLocalName, columnNamespace); columns[idColumn] = col; if (col.ColumnName.StartsWith("xml", StringComparison.OrdinalIgnoreCase)) { HandleSpecialColumn(col, nameTable, columns); } return true; } private bool AddColumnSchema(XmlNameTable nameTable, DataColumn col, XmlNodeIdHashtable columns) { string _columnLocalName = XmlConvert.EncodeLocalName(col.ColumnName); string columnLocalName = nameTable.Get(_columnLocalName); // Look it up in a name table if(columnLocalName == null) { // Not found? columnLocalName = nameTable.Add(_columnLocalName); // Add it } col.encodedColumnName = columnLocalName; // And set it back string columnNamespace = nameTable.Get(col.Namespace ); // Get column namespace from nametable if(columnNamespace == null) { // Not found ? columnNamespace = nameTable.Add(col.Namespace); // Add it } else { if (col._columnUri != null ) // Update namespace col._columnUri = columnNamespace; } // Create XmlNodeIdentety // for this column XmlNodeIdentety idColumn = new XmlNodeIdentety(columnLocalName, columnNamespace); columns[idColumn] = col; // And add it to hashtable if (col.ColumnName.StartsWith("xml", StringComparison.OrdinalIgnoreCase)) { HandleSpecialColumn(col, nameTable, columns); } return true; } private void BuildIdentityMap(DataSet dataSet, XmlNameTable nameTable) { this.tableSchemaMap = new XmlNodeIdHashtable(dataSet.Tables.Count); foreach(DataTable t in dataSet.Tables) { TableSchemaInfo tableSchemaInfo = AddTableSchema(t, nameTable); if(tableSchemaInfo != null) { foreach( DataColumn c in t.Columns ) { // don't include auto-generated PK, FK and any hidden columns to be part of mapping if (IsMappedColumn(c)) { AddColumnSchema(c, nameTable, tableSchemaInfo.ColumnsSchemaMap); } } } } } // This one is used while reading data with preloaded schema private void BuildIdentityMap(XmlNameTable nameTable, DataSet dataSet) { this.tableSchemaMap = new XmlNodeIdHashtable(dataSet.Tables.Count); // This hash table contains // tables schemas as TableSchemaInfo objects // These objects holds reference to the table. // Hash tables with columns schema maps // and child tables schema maps string dsNamespace = nameTable.Get(dataSet.Namespace); // Attept to look up DataSet namespace // in the name table if (dsNamespace == null) { // Found ? dsNamespace = nameTable.Add(dataSet.Namespace); // Nope. Add it } dataSet.namespaceURI = dsNamespace; // Set a DataSet namespace URI foreach(DataTable t in dataSet.Tables) { // For each table TableSchemaInfo tableSchemaInfo = AddTableSchema(nameTable, t); // Add table schema info to hash table if(tableSchemaInfo != null) { foreach( DataColumn c in t.Columns ) { // Add column schema map // don't include auto-generated PK, FK and any hidden columns to be part of mapping if (IsMappedColumn(c)) { // If mapped column AddColumnSchema(nameTable, c, tableSchemaInfo.ColumnsSchemaMap); } // Add it to the map } // Add child nested tables to the schema foreach( DataRelation r in t.ChildRelations ) { // Do we have a child tables ? if (r.Nested) { // Is it nested? // don't include non nested tables // Handle namespaces and names as usuall string _tableLocalName = XmlConvert.EncodeLocalName(r.ChildTable.TableName); string tableLocalName = nameTable.Get(_tableLocalName); if(tableLocalName == null) { tableLocalName = nameTable.Add(_tableLocalName); } string tableNamespace = nameTable.Get(r.ChildTable.Namespace ); if(tableNamespace == null) { tableNamespace = nameTable.Add(r.ChildTable.Namespace); } XmlNodeIdentety idTable = new XmlNodeIdentety(tableLocalName, tableNamespace); tableSchemaInfo.ColumnsSchemaMap[idTable] = r.ChildTable; } } } } } // Used for inference private void BuildIdentityMap(DataTable dataTable, XmlNameTable nameTable) { this.tableSchemaMap = new XmlNodeIdHashtable(1); TableSchemaInfo tableSchemaInfo = AddTableSchema(dataTable, nameTable); if(tableSchemaInfo != null) { foreach( DataColumn c in dataTable.Columns ) { // don't include auto-generated PK, FK and any hidden columns to be part of mapping if (IsMappedColumn(c)) { AddColumnSchema(c, nameTable, tableSchemaInfo.ColumnsSchemaMap); } } } } // This one is used while reading data with preloaded schema private void BuildIdentityMap(XmlNameTable nameTable, DataTable dataTable) { ArrayList tableList = GetSelfAndDescendants(dataTable); // Get list of tables we're loading // This includes our table and // related tables tree this.tableSchemaMap = new XmlNodeIdHashtable( tableList.Count ); // Create hash table to hold all // tables to load. foreach (DataTable t in tableList) { // For each table TableSchemaInfo tableSchemaInfo = AddTableSchema(nameTable, t ); // Create schema info if(tableSchemaInfo != null) { foreach( DataColumn c in t.Columns ) { // Add column information // don't include auto-generated PK, FK and any hidden columns to be part of mapping if (IsMappedColumn(c)) { AddColumnSchema(nameTable, c, tableSchemaInfo.ColumnsSchemaMap); } } foreach( DataRelation r in t.ChildRelations ) { // Add nested tables information if (r.Nested) { // Is it nested? // don't include non nested tables // Handle namespaces and names as usuall string _tableLocalName = XmlConvert.EncodeLocalName(r.ChildTable.TableName); string tableLocalName = nameTable.Get(_tableLocalName); if(tableLocalName == null) { tableLocalName = nameTable.Add(_tableLocalName); } string tableNamespace = nameTable.Get(r.ChildTable.Namespace ); if(tableNamespace == null) { tableNamespace = nameTable.Add(r.ChildTable.Namespace); } XmlNodeIdentety idTable = new XmlNodeIdentety(tableLocalName, tableNamespace); tableSchemaInfo.ColumnsSchemaMap[idTable] = r.ChildTable; } } } } } private ArrayList GetSelfAndDescendants(DataTable dt) { // breadth-first ArrayList tableList = new ArrayList(); tableList.Add(dt); int nCounter = 0; while (nCounter < tableList.Count) { foreach(DataRelation childRelations in ((DataTable)tableList[nCounter]).ChildRelations) { if (!tableList.Contains(childRelations.ChildTable)) tableList.Add(childRelations.ChildTable); } nCounter++; } return tableList; } // Used to infer schema and top most node public object GetColumnSchema(XmlNode node, bool fIgnoreNamespace) { Debug.Assert(node != null, "Argument validation"); TableSchemaInfo tableSchemaInfo = null; XmlNode nodeRegion = (node.NodeType == XmlNodeType.Attribute) ? ((XmlAttribute)node).OwnerElement : node.ParentNode; do { if(nodeRegion == null || nodeRegion.NodeType != XmlNodeType.Element) { return null; } tableSchemaInfo = (TableSchemaInfo) (fIgnoreNamespace ? tableSchemaMap[nodeRegion.LocalName] : tableSchemaMap[nodeRegion]); nodeRegion = nodeRegion.ParentNode; } while(tableSchemaInfo == null); if (fIgnoreNamespace) return tableSchemaInfo.ColumnsSchemaMap[node.LocalName]; else return tableSchemaInfo.ColumnsSchemaMap[node]; } public object GetColumnSchema(DataTable table, XmlReader dataReader, bool fIgnoreNamespace){ if ((lastTableSchemaInfo == null) || (lastTableSchemaInfo.TableSchema != table)) { lastTableSchemaInfo = (TableSchemaInfo)(fIgnoreNamespace ? tableSchemaMap[table.EncodedTableName] : tableSchemaMap[table]); } if (fIgnoreNamespace) return lastTableSchemaInfo.ColumnsSchemaMap[dataReader.LocalName]; return lastTableSchemaInfo.ColumnsSchemaMap[dataReader]; } // Used to infer schema public object GetSchemaForNode(XmlNode node, bool fIgnoreNamespace) { TableSchemaInfo tableSchemaInfo = null; if (node.NodeType == XmlNodeType.Element) { // If element tableSchemaInfo = (TableSchemaInfo) (fIgnoreNamespace ? tableSchemaMap[node.LocalName] : tableSchemaMap[node]); } // Look up table schema info for it if (tableSchemaInfo != null) { // Got info ? return tableSchemaInfo.TableSchema; // Yes, Return table } return GetColumnSchema(node, fIgnoreNamespace); // Attempt to locate column } public DataTable GetTableForNode(XmlReader node, bool fIgnoreNamespace) { TableSchemaInfo tableSchemaInfo = (TableSchemaInfo) (fIgnoreNamespace ? tableSchemaMap[node.LocalName] : tableSchemaMap[node]); if (tableSchemaInfo != null) { lastTableSchemaInfo = tableSchemaInfo; return lastTableSchemaInfo.TableSchema; } return null; } private void HandleSpecialColumn(DataColumn col, XmlNameTable nameTable, XmlNodeIdHashtable columns) { // if column name starts with xml, we encode it manualy and add it for look up Debug.Assert(col.ColumnName.StartsWith("xml", StringComparison.OrdinalIgnoreCase), "column name should start with xml"); string tempColumnName; if ('x' == col.ColumnName[0]) { tempColumnName = "_x0078_"; // lower case xml... -> _x0078_ml... } else { tempColumnName = "_x0058_"; // upper case Xml... -> _x0058_ml... } tempColumnName += col.ColumnName.Substring(1); if(nameTable.Get(tempColumnName) == null) { nameTable.Add(tempColumnName); } string columnNamespace = nameTable.Get(col.Namespace); XmlNodeIdentety idColumn = new XmlNodeIdentety(tempColumnName, columnNamespace); columns[idColumn] = col; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //[....] //----------------------------------------------------------------------------- namespace System.Data { using System; using System.Xml; using System.Collections; using System.Diagnostics; using System.Globalization; // This is an internal helper class used during Xml load to DataSet/DataDocument. // XmlToDatasetMap class provides functionality for binding elemants/atributes // to DataTable / DataColumn internal sealed class XmlToDatasetMap { private sealed class XmlNodeIdentety { public string LocalName; public string NamespaceURI; public XmlNodeIdentety(string localName, string namespaceURI) { this.LocalName = localName; this.NamespaceURI = namespaceURI; } override public int GetHashCode() { return ((object) LocalName).GetHashCode(); } override public bool Equals(object obj) { XmlNodeIdentety id = (XmlNodeIdentety) obj; return ( (String.Compare(this.LocalName, id.LocalName, StringComparison.OrdinalIgnoreCase) == 0) && (String.Compare(this.NamespaceURI, id.NamespaceURI, StringComparison.OrdinalIgnoreCase) == 0) ); } } // This class exist to avoid alocatin of XmlNodeIdentety to every acces to the hash table. // Unfortunetely XmlNode doesn't export single identety object. internal sealed class XmlNodeIdHashtable : Hashtable { private XmlNodeIdentety id = new XmlNodeIdentety(string.Empty, string.Empty); public XmlNodeIdHashtable(Int32 capacity) : base(capacity) {} public object this[XmlNode node] { get { id.LocalName = node.LocalName; id.NamespaceURI = node.NamespaceURI; return this[id]; } } public object this[XmlReader dataReader] { get { id.LocalName = dataReader.LocalName; id.NamespaceURI = dataReader.NamespaceURI; return this[id]; } } public object this[DataTable table] { get { id.LocalName = table.EncodedTableName; id.NamespaceURI = table.Namespace; return this[id]; } } public object this[string name] { get { id.LocalName = name; id.NamespaceURI = String.Empty; return this[id]; } } } private sealed class TableSchemaInfo { public DataTable TableSchema; public XmlNodeIdHashtable ColumnsSchemaMap; public TableSchemaInfo(DataTable tableSchema) { this.TableSchema = tableSchema; this.ColumnsSchemaMap = new XmlNodeIdHashtable(tableSchema.Columns.Count); } } XmlNodeIdHashtable tableSchemaMap; // Holds all the tables information TableSchemaInfo lastTableSchemaInfo = null; // Used to infer schema public XmlToDatasetMap(DataSet dataSet, XmlNameTable nameTable) { Debug.Assert(dataSet != null, "DataSet can't be null"); Debug.Assert(nameTable != null, "NameTable can't be null"); BuildIdentityMap(dataSet, nameTable); } // Used to read data with known schema public XmlToDatasetMap(XmlNameTable nameTable, DataSet dataSet) { Debug.Assert(dataSet != null, "DataSet can't be null"); Debug.Assert(nameTable != null, "NameTable can't be null"); BuildIdentityMap(nameTable, dataSet); } // Used to infer schema public XmlToDatasetMap(DataTable dataTable, XmlNameTable nameTable) { Debug.Assert(dataTable != null, "DataTable can't be null"); Debug.Assert(nameTable != null, "NameTable can't be null"); BuildIdentityMap(dataTable, nameTable); } // Used to read data with known schema public XmlToDatasetMap(XmlNameTable nameTable, DataTable dataTable) { Debug.Assert(dataTable != null, "DataTable can't be null"); Debug.Assert(nameTable != null, "NameTable can't be null"); BuildIdentityMap(nameTable, dataTable); } static internal bool IsMappedColumn(DataColumn c) { return (c.ColumnMapping != MappingType.Hidden); } // Used to infere schema private TableSchemaInfo AddTableSchema(DataTable table, XmlNameTable nameTable) { // [....]: Because in our case reader already read the document all names that we can meet in the // document already has an entry in NameTable. // If in future we will build identity map before reading XML we can replace Get() to Add() // [....]: GetIdentity is called from two places: BuildIdentityMap() and LoadRows() // First case deals with decoded names; Second one with encoded names. // We decided encoded names in first case (instead of decoding them in second) // because it save us time in LoadRows(). We have, as usual, more data them schemas string tableLocalName = nameTable.Get(table.EncodedTableName); string tableNamespace = nameTable.Get(table.Namespace ); if(tableLocalName == null) { // because name of this table isn't present in XML we don't need mapping for it. // Less mapping faster we work. return null; } TableSchemaInfo tableSchemaInfo = new TableSchemaInfo(table); tableSchemaMap[new XmlNodeIdentety(tableLocalName, tableNamespace)] = tableSchemaInfo; return tableSchemaInfo; } private TableSchemaInfo AddTableSchema(XmlNameTable nameTable, DataTable table) { // [....]:This is the opposite of the previous function: // we populate the nametable so that the hash comparison can happen as // object comparison instead of strings. // [....]: GetIdentity is called from two places: BuildIdentityMap() and LoadRows() // First case deals with decoded names; Second one with encoded names. // We decided encoded names in first case (instead of decoding them in second) // because it save us time in LoadRows(). We have, as usual, more data them schemas string _tableLocalName = table.EncodedTableName; // Table name string tableLocalName = nameTable.Get(_tableLocalName); // Look it up in nametable if(tableLocalName == null) { // If not found tableLocalName = nameTable.Add(_tableLocalName); // Add it } table.encodedTableName = tableLocalName; // And set it back string tableNamespace = nameTable.Get(table.Namespace); // Look ip table namespace if (tableNamespace == null) { // If not found tableNamespace = nameTable.Add(table.Namespace); // Add it } else { if (table.tableNamespace != null) // Update table namespace table.tableNamespace = tableNamespace; } TableSchemaInfo tableSchemaInfo = new TableSchemaInfo(table); // Create new table schema info tableSchemaMap[new XmlNodeIdentety(tableLocalName, tableNamespace)] = tableSchemaInfo; // And add it to the hashtable return tableSchemaInfo; // Return it as we have to populate // Column schema map and Child table // schema map in it } private bool AddColumnSchema(DataColumn col, XmlNameTable nameTable, XmlNodeIdHashtable columns) { string columnLocalName = nameTable.Get(col.EncodedColumnName ); string columnNamespace = nameTable.Get(col.Namespace ); if(columnLocalName == null) { return false; } XmlNodeIdentety idColumn = new XmlNodeIdentety(columnLocalName, columnNamespace); columns[idColumn] = col; if (col.ColumnName.StartsWith("xml", StringComparison.OrdinalIgnoreCase)) { HandleSpecialColumn(col, nameTable, columns); } return true; } private bool AddColumnSchema(XmlNameTable nameTable, DataColumn col, XmlNodeIdHashtable columns) { string _columnLocalName = XmlConvert.EncodeLocalName(col.ColumnName); string columnLocalName = nameTable.Get(_columnLocalName); // Look it up in a name table if(columnLocalName == null) { // Not found? columnLocalName = nameTable.Add(_columnLocalName); // Add it } col.encodedColumnName = columnLocalName; // And set it back string columnNamespace = nameTable.Get(col.Namespace ); // Get column namespace from nametable if(columnNamespace == null) { // Not found ? columnNamespace = nameTable.Add(col.Namespace); // Add it } else { if (col._columnUri != null ) // Update namespace col._columnUri = columnNamespace; } // Create XmlNodeIdentety // for this column XmlNodeIdentety idColumn = new XmlNodeIdentety(columnLocalName, columnNamespace); columns[idColumn] = col; // And add it to hashtable if (col.ColumnName.StartsWith("xml", StringComparison.OrdinalIgnoreCase)) { HandleSpecialColumn(col, nameTable, columns); } return true; } private void BuildIdentityMap(DataSet dataSet, XmlNameTable nameTable) { this.tableSchemaMap = new XmlNodeIdHashtable(dataSet.Tables.Count); foreach(DataTable t in dataSet.Tables) { TableSchemaInfo tableSchemaInfo = AddTableSchema(t, nameTable); if(tableSchemaInfo != null) { foreach( DataColumn c in t.Columns ) { // don't include auto-generated PK, FK and any hidden columns to be part of mapping if (IsMappedColumn(c)) { AddColumnSchema(c, nameTable, tableSchemaInfo.ColumnsSchemaMap); } } } } } // This one is used while reading data with preloaded schema private void BuildIdentityMap(XmlNameTable nameTable, DataSet dataSet) { this.tableSchemaMap = new XmlNodeIdHashtable(dataSet.Tables.Count); // This hash table contains // tables schemas as TableSchemaInfo objects // These objects holds reference to the table. // Hash tables with columns schema maps // and child tables schema maps string dsNamespace = nameTable.Get(dataSet.Namespace); // Attept to look up DataSet namespace // in the name table if (dsNamespace == null) { // Found ? dsNamespace = nameTable.Add(dataSet.Namespace); // Nope. Add it } dataSet.namespaceURI = dsNamespace; // Set a DataSet namespace URI foreach(DataTable t in dataSet.Tables) { // For each table TableSchemaInfo tableSchemaInfo = AddTableSchema(nameTable, t); // Add table schema info to hash table if(tableSchemaInfo != null) { foreach( DataColumn c in t.Columns ) { // Add column schema map // don't include auto-generated PK, FK and any hidden columns to be part of mapping if (IsMappedColumn(c)) { // If mapped column AddColumnSchema(nameTable, c, tableSchemaInfo.ColumnsSchemaMap); } // Add it to the map } // Add child nested tables to the schema foreach( DataRelation r in t.ChildRelations ) { // Do we have a child tables ? if (r.Nested) { // Is it nested? // don't include non nested tables // Handle namespaces and names as usuall string _tableLocalName = XmlConvert.EncodeLocalName(r.ChildTable.TableName); string tableLocalName = nameTable.Get(_tableLocalName); if(tableLocalName == null) { tableLocalName = nameTable.Add(_tableLocalName); } string tableNamespace = nameTable.Get(r.ChildTable.Namespace ); if(tableNamespace == null) { tableNamespace = nameTable.Add(r.ChildTable.Namespace); } XmlNodeIdentety idTable = new XmlNodeIdentety(tableLocalName, tableNamespace); tableSchemaInfo.ColumnsSchemaMap[idTable] = r.ChildTable; } } } } } // Used for inference private void BuildIdentityMap(DataTable dataTable, XmlNameTable nameTable) { this.tableSchemaMap = new XmlNodeIdHashtable(1); TableSchemaInfo tableSchemaInfo = AddTableSchema(dataTable, nameTable); if(tableSchemaInfo != null) { foreach( DataColumn c in dataTable.Columns ) { // don't include auto-generated PK, FK and any hidden columns to be part of mapping if (IsMappedColumn(c)) { AddColumnSchema(c, nameTable, tableSchemaInfo.ColumnsSchemaMap); } } } } // This one is used while reading data with preloaded schema private void BuildIdentityMap(XmlNameTable nameTable, DataTable dataTable) { ArrayList tableList = GetSelfAndDescendants(dataTable); // Get list of tables we're loading // This includes our table and // related tables tree this.tableSchemaMap = new XmlNodeIdHashtable( tableList.Count ); // Create hash table to hold all // tables to load. foreach (DataTable t in tableList) { // For each table TableSchemaInfo tableSchemaInfo = AddTableSchema(nameTable, t ); // Create schema info if(tableSchemaInfo != null) { foreach( DataColumn c in t.Columns ) { // Add column information // don't include auto-generated PK, FK and any hidden columns to be part of mapping if (IsMappedColumn(c)) { AddColumnSchema(nameTable, c, tableSchemaInfo.ColumnsSchemaMap); } } foreach( DataRelation r in t.ChildRelations ) { // Add nested tables information if (r.Nested) { // Is it nested? // don't include non nested tables // Handle namespaces and names as usuall string _tableLocalName = XmlConvert.EncodeLocalName(r.ChildTable.TableName); string tableLocalName = nameTable.Get(_tableLocalName); if(tableLocalName == null) { tableLocalName = nameTable.Add(_tableLocalName); } string tableNamespace = nameTable.Get(r.ChildTable.Namespace ); if(tableNamespace == null) { tableNamespace = nameTable.Add(r.ChildTable.Namespace); } XmlNodeIdentety idTable = new XmlNodeIdentety(tableLocalName, tableNamespace); tableSchemaInfo.ColumnsSchemaMap[idTable] = r.ChildTable; } } } } } private ArrayList GetSelfAndDescendants(DataTable dt) { // breadth-first ArrayList tableList = new ArrayList(); tableList.Add(dt); int nCounter = 0; while (nCounter < tableList.Count) { foreach(DataRelation childRelations in ((DataTable)tableList[nCounter]).ChildRelations) { if (!tableList.Contains(childRelations.ChildTable)) tableList.Add(childRelations.ChildTable); } nCounter++; } return tableList; } // Used to infer schema and top most node public object GetColumnSchema(XmlNode node, bool fIgnoreNamespace) { Debug.Assert(node != null, "Argument validation"); TableSchemaInfo tableSchemaInfo = null; XmlNode nodeRegion = (node.NodeType == XmlNodeType.Attribute) ? ((XmlAttribute)node).OwnerElement : node.ParentNode; do { if(nodeRegion == null || nodeRegion.NodeType != XmlNodeType.Element) { return null; } tableSchemaInfo = (TableSchemaInfo) (fIgnoreNamespace ? tableSchemaMap[nodeRegion.LocalName] : tableSchemaMap[nodeRegion]); nodeRegion = nodeRegion.ParentNode; } while(tableSchemaInfo == null); if (fIgnoreNamespace) return tableSchemaInfo.ColumnsSchemaMap[node.LocalName]; else return tableSchemaInfo.ColumnsSchemaMap[node]; } public object GetColumnSchema(DataTable table, XmlReader dataReader, bool fIgnoreNamespace){ if ((lastTableSchemaInfo == null) || (lastTableSchemaInfo.TableSchema != table)) { lastTableSchemaInfo = (TableSchemaInfo)(fIgnoreNamespace ? tableSchemaMap[table.EncodedTableName] : tableSchemaMap[table]); } if (fIgnoreNamespace) return lastTableSchemaInfo.ColumnsSchemaMap[dataReader.LocalName]; return lastTableSchemaInfo.ColumnsSchemaMap[dataReader]; } // Used to infer schema public object GetSchemaForNode(XmlNode node, bool fIgnoreNamespace) { TableSchemaInfo tableSchemaInfo = null; if (node.NodeType == XmlNodeType.Element) { // If element tableSchemaInfo = (TableSchemaInfo) (fIgnoreNamespace ? tableSchemaMap[node.LocalName] : tableSchemaMap[node]); } // Look up table schema info for it if (tableSchemaInfo != null) { // Got info ? return tableSchemaInfo.TableSchema; // Yes, Return table } return GetColumnSchema(node, fIgnoreNamespace); // Attempt to locate column } public DataTable GetTableForNode(XmlReader node, bool fIgnoreNamespace) { TableSchemaInfo tableSchemaInfo = (TableSchemaInfo) (fIgnoreNamespace ? tableSchemaMap[node.LocalName] : tableSchemaMap[node]); if (tableSchemaInfo != null) { lastTableSchemaInfo = tableSchemaInfo; return lastTableSchemaInfo.TableSchema; } return null; } private void HandleSpecialColumn(DataColumn col, XmlNameTable nameTable, XmlNodeIdHashtable columns) { // if column name starts with xml, we encode it manualy and add it for look up Debug.Assert(col.ColumnName.StartsWith("xml", StringComparison.OrdinalIgnoreCase), "column name should start with xml"); string tempColumnName; if ('x' == col.ColumnName[0]) { tempColumnName = "_x0078_"; // lower case xml... -> _x0078_ml... } else { tempColumnName = "_x0058_"; // upper case Xml... -> _x0058_ml... } tempColumnName += col.ColumnName.Substring(1); if(nameTable.Get(tempColumnName) == null) { nameTable.Add(tempColumnName); } string columnNamespace = nameTable.Get(col.Namespace); XmlNodeIdentety idColumn = new XmlNodeIdentety(tempColumnName, columnNamespace); columns[idColumn] = col; } } } // 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
- ServiceRouteHandler.cs
- _ListenerResponseStream.cs
- ZoneButton.cs
- HtmlLiteralTextAdapter.cs
- SelectionChangedEventArgs.cs
- ScrollBar.cs
- MemberHolder.cs
- MimeFormReflector.cs
- IUnknownConstantAttribute.cs
- MobileContainerDesigner.cs
- RangeValidator.cs
- BooleanSwitch.cs
- ConfigurationStrings.cs
- TypeLibConverter.cs
- ScriptControlManager.cs
- GridViewCancelEditEventArgs.cs
- CompilationSection.cs
- cryptoapiTransform.cs
- StringValidatorAttribute.cs
- AutoResetEvent.cs
- Rect3D.cs
- InkCanvasSelectionAdorner.cs
- XPathNavigatorReader.cs
- EventBookmark.cs
- Array.cs
- SoapEnumAttribute.cs
- IntellisenseTextBox.designer.cs
- SpecularMaterial.cs
- ColumnMapTranslator.cs
- SplineQuaternionKeyFrame.cs
- RootDesignerSerializerAttribute.cs
- RichTextBoxConstants.cs
- StructureChangedEventArgs.cs
- PresentationSource.cs
- ChildTable.cs
- TemplateContent.cs
- FontFaceLayoutInfo.cs
- BuilderPropertyEntry.cs
- XNodeValidator.cs
- FileRecordSequenceCompletedAsyncResult.cs
- RequiredAttributeAttribute.cs
- SdlChannelSink.cs
- CompilerResults.cs
- KoreanCalendar.cs
- TimeSpan.cs
- QueryCacheKey.cs
- MatrixTransform3D.cs
- DataGridViewRowCancelEventArgs.cs
- PixelShader.cs
- WebAdminConfigurationHelper.cs
- CodeObjectCreateExpression.cs
- PowerStatus.cs
- MembershipSection.cs
- InvalidContentTypeException.cs
- XmlSchemaExporter.cs
- ProcessHostFactoryHelper.cs
- XsltContext.cs
- MenuItem.cs
- PanelDesigner.cs
- Accessors.cs
- AsynchronousChannel.cs
- InkCanvasInnerCanvas.cs
- SecurityElement.cs
- SafeTokenHandle.cs
- SqlPersonalizationProvider.cs
- PerformanceCounterScope.cs
- UseManagedPresentationElement.cs
- HwndSourceKeyboardInputSite.cs
- GPRECT.cs
- HttpApplication.cs
- Selector.cs
- RawAppCommandInputReport.cs
- TraceContext.cs
- ExpressionHelper.cs
- HashFinalRequest.cs
- activationcontext.cs
- WorkflowExecutor.cs
- AncestorChangedEventArgs.cs
- WindowsListViewSubItem.cs
- DataGrid.cs
- TextRangeSerialization.cs
- AutoGeneratedFieldProperties.cs
- DetailsViewModeEventArgs.cs
- GroupItem.cs
- DomNameTable.cs
- KeyEventArgs.cs
- DeploymentSection.cs
- URLAttribute.cs
- EntryPointNotFoundException.cs
- XPathNodeInfoAtom.cs
- ErrorWebPart.cs
- ComponentResourceKeyConverter.cs
- XamlGridLengthSerializer.cs
- SerialErrors.cs
- ListViewPagedDataSource.cs
- AuthorizationSection.cs
- DirectoryLocalQuery.cs
- IndexingContentUnit.cs
- UshortList2.cs
- CornerRadiusConverter.cs