//------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // // [....] // [....] //------------------------------------------------------------------------------ namespace System.Data { using System; using System.Text; using System.Runtime.Serialization; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Xml; using System.Xml.Serialization; #if !NO_CONFIGURATION using System.Xml.Serialization.Advanced; #endif using System.Xml.Schema; using System.Runtime.Serialization.Formatters.Binary; //Binary Formatter using System.CodeDom; using System.CodeDom.Compiler; using System.Configuration; using System.Data.Common; using System.Runtime.Versioning; using System.Runtime.CompilerServices; /// /// /// Represents an in-memory cache of data. /// /// [ ResDescriptionAttribute(Res.DataSetDescr), DefaultProperty("DataSetName"), ToolboxItem("Microsoft.VSDesigner.Data.VS.DataSetToolboxItem, " + AssemblyRef.MicrosoftVSDesigner), Designer("Microsoft.VSDesigner.Data.VS.DataSetDesigner, " + AssemblyRef.MicrosoftVSDesigner), Serializable, XmlSchemaProvider("GetDataSetSchema"), XmlRoot("DataSet") ] public class DataSet : MarshalByValueComponent, System.ComponentModel.IListSource, IXmlSerializable, ISupportInitializeNotification, ISerializable { private DataViewManager defaultViewManager; // Public Collections private readonly DataTableCollection tableCollection; private readonly DataRelationCollection relationCollection; internal PropertyCollection extendedProperties = null; private string dataSetName = "NewDataSet"; private string _datasetPrefix = String.Empty; internal string namespaceURI = string.Empty; private bool enforceConstraints = true; private const String KEY_XMLSCHEMA = "XmlSchema"; private const String KEY_XMLDIFFGRAM = "XmlDiffGram"; // globalization stuff private bool _caseSensitive; private CultureInfo _culture; private bool _cultureUserSet; // Internal definitions internal bool fInReadXml = false; internal bool fInLoadDiffgram = false; internal bool fTopLevelTable = false; internal bool fInitInProgress = false; internal bool fEnableCascading = true; internal bool fIsSchemaLoading = false; private bool fBoundToDocument; // for XmlDataDocument // Events private PropertyChangedEventHandler onPropertyChangingDelegate; private MergeFailedEventHandler onMergeFailed; private DataRowCreatedEventHandler onDataRowCreated; // Internal for XmlDataDocument only private DataSetClearEventhandler onClearFunctionCalled; // Internal for XmlDataDocument only private System.EventHandler onInitialized; internal readonly static DataTable[] zeroTables = new DataTable[0]; internal string mainTableName = ""; //default remoting format is XML private SerializationFormat _remotingFormat = SerializationFormat.Xml; private object _defaultViewManagerLock = new Object(); private static int _objectTypeCount; // Bid counter private readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount); private static XmlSchemaComplexType schemaTypeForWSDL = null; internal bool UseDataSetSchemaOnly; // UseDataSetSchemaOnly , for YUKON internal bool UdtIsWrapped; // if UDT is wrapped , for YUKON /// /// Initializes a new instance of the class. /// public DataSet() { GC.SuppressFinalize(this); Bid.Trace(" %d#\n", ObjectID); // others will call this constr // Set default locale this.tableCollection = new DataTableCollection(this); this.relationCollection = new DataRelationCollection.DataSetRelationCollection(this); _culture = CultureInfo.CurrentCulture; // Set default locale } /// /// Initializes a new instance of a /// class with the given name. /// public DataSet(string dataSetName) : this() { this.DataSetName = dataSetName; } [ DefaultValue(SerializationFormat.Xml) ] public SerializationFormat RemotingFormat { get { return _remotingFormat; } set { if (value != SerializationFormat.Binary && value != SerializationFormat.Xml) { throw ExceptionBuilder.InvalidRemotingFormat(value); } _remotingFormat = value; // this property is inherited to DataTable from DataSet.So we set this value to DataTable also for (int i = 0; i < Tables.Count; i++) { Tables[i].RemotingFormat = value; } } } [BrowsableAttribute(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual SchemaSerializationMode SchemaSerializationMode { //Typed DataSet calls into this get { return SchemaSerializationMode.IncludeSchema; } set { if (value != SchemaSerializationMode.IncludeSchema) { throw ExceptionBuilder.CannotChangeSchemaSerializationMode(); } } } // Check whether the stream is binary serialized. // 'static' function that consumes SerializationInfo protected bool IsBinarySerialized(SerializationInfo info, StreamingContext context) {// mainly for typed DS // our default remoting format is XML SerializationFormat remotingFormat = SerializationFormat.Xml; SerializationInfoEnumerator e = info.GetEnumerator(); while (e.MoveNext()) { if (e.Name == "DataSet.RemotingFormat") {//DataSet.RemotingFormat does not exist in V1/V1.1 versions remotingFormat = (SerializationFormat)e.Value; break; } } return (remotingFormat == SerializationFormat.Binary); } // Should Schema be included during Serialization // 'static' function that consumes SerializationInfo protected SchemaSerializationMode DetermineSchemaSerializationMode(SerializationInfo info, StreamingContext context) { //Typed DataSet calls into this SchemaSerializationMode schemaSerializationMode = SchemaSerializationMode.IncludeSchema; SerializationInfoEnumerator e = info.GetEnumerator(); while (e.MoveNext()) { if (e.Name == "SchemaSerializationMode.DataSet") { //SchemaSerializationMode.DataSet does not exist in V1/V1.1 versions schemaSerializationMode = (SchemaSerializationMode)e.Value; break; } } return schemaSerializationMode; } protected SchemaSerializationMode DetermineSchemaSerializationMode(XmlReader reader) { //Typed DataSet calls into this SchemaSerializationMode schemaSerializationMode = SchemaSerializationMode.IncludeSchema; reader.MoveToContent(); if (reader.NodeType == XmlNodeType.Element) { if (reader.HasAttributes) { string attribValue = reader.GetAttribute(Keywords.MSD_SCHEMASERIALIZATIONMODE, Keywords.MSDNS); if ((String.Compare(attribValue, Keywords.MSD_EXCLUDESCHEMA, StringComparison.OrdinalIgnoreCase) == 0)) { schemaSerializationMode = SchemaSerializationMode.ExcludeSchema; } else if ((String.Compare(attribValue, Keywords.MSD_INCLUDESCHEMA, StringComparison.OrdinalIgnoreCase) == 0)) { schemaSerializationMode = SchemaSerializationMode.IncludeSchema; } else if (attribValue != null) { // if attrib does not exist, then don't throw throw ExceptionBuilder.InvalidSchemaSerializationMode(typeof(SchemaSerializationMode), attribValue); } } } return schemaSerializationMode; } // Deserialize all the tables data of the dataset from binary/xml stream. // 'instance' method that consumes SerializationInfo protected void GetSerializationData(SerializationInfo info, StreamingContext context) {// mainly for typed DS SerializationFormat remotingFormat = SerializationFormat.Xml; SerializationInfoEnumerator e = info.GetEnumerator(); while (e.MoveNext()) { if (e.Name == "DataSet.RemotingFormat") { //DataSet.RemotingFormat does not exist in V1/V1.1 versions remotingFormat = (SerializationFormat)e.Value; break; } } DeserializeDataSetData(info, context, remotingFormat); } // Deserialize all the tables schema and data of the dataset from binary/xml stream. protected DataSet(SerializationInfo info, StreamingContext context) : this(info, context, true) { } protected DataSet(SerializationInfo info, StreamingContext context, bool ConstructSchema) : this() { SerializationFormat remotingFormat = SerializationFormat.Xml; SchemaSerializationMode schemaSerializationMode = SchemaSerializationMode.IncludeSchema; SerializationInfoEnumerator e = info.GetEnumerator(); while (e.MoveNext()) { switch (e.Name) { case "DataSet.RemotingFormat": //DataSet.RemotingFormat does not exist in V1/V1.1 versions remotingFormat = (SerializationFormat)e.Value; break; case "SchemaSerializationMode.DataSet": //SchemaSerializationMode.DataSet does not exist in V1/V1.1 versions schemaSerializationMode = (SchemaSerializationMode)e.Value; break; } } if (schemaSerializationMode == SchemaSerializationMode.ExcludeSchema) { InitializeDerivedDataSet(); } // adding back this check will fix typed dataset XML remoting, but we have to fix case that // a class inherits from DataSet and just relies on DataSet to deserialize (see SQL BU DT 374717) // to fix that case also, we need to add a flag and add it to below check so return (no-op) will be // conditional (flag needs to be set in TypedDataSet if (remotingFormat == SerializationFormat.Xml && !ConstructSchema /* && this.GetType() != typeof(DataSet)*/) { return; //For typed dataset xml remoting, this is a no-op } DeserializeDataSet(info, context, remotingFormat, schemaSerializationMode); } [System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Flags = System.Security.Permissions.SecurityPermissionFlag.SerializationFormatter)] public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { SerializationFormat remotingFormat = RemotingFormat; SerializeDataSet(info, context, remotingFormat); } // Deserialize all the tables data of the dataset from binary/xml stream. protected virtual void InitializeDerivedDataSet() { return; } // Serialize all the tables. private void SerializeDataSet(SerializationInfo info, StreamingContext context, SerializationFormat remotingFormat) { Debug.Assert(info != null); info.AddValue("DataSet.RemotingVersion", new Version(2, 0)); // SqlHotFix 299, SerializationFormat enumeration types don't exist in V1.1 SP1 if (SerializationFormat.Xml != remotingFormat) { info.AddValue("DataSet.RemotingFormat", remotingFormat); } // SqlHotFix 299, SchemaSerializationMode enumeration types don't exist in V1.1 SP1 if (SchemaSerializationMode.IncludeSchema != SchemaSerializationMode) { //SkipSchemaDuringSerialization info.AddValue("SchemaSerializationMode.DataSet", SchemaSerializationMode); } if (remotingFormat != SerializationFormat.Xml) { if (SchemaSerializationMode == SchemaSerializationMode.IncludeSchema) { //DataSet public state properties SerializeDataSetProperties(info, context); //Tables Count info.AddValue("DataSet.Tables.Count", Tables.Count); //Tables, Columns, Rows for (int i = 0; i < Tables.Count; i++) { BinaryFormatter bf = new BinaryFormatter(null, new StreamingContext(context.State, false)); MemoryStream memStream = new MemoryStream(); bf.Serialize(memStream, Tables[i]); memStream.Position = 0; info.AddValue(String.Format(CultureInfo.InvariantCulture, "DataSet.Tables_{0}", i), memStream.GetBuffer()); } //Constraints for (int i = 0; i < Tables.Count; i++) { Tables[i].SerializeConstraints(info, context, i, true); } //Relations SerializeRelations(info, context); //Expression Columns for (int i = 0; i < Tables.Count; i++) { Tables[i].SerializeExpressionColumns(info, context, i); } } else { //Serialize DataSet public properties. SerializeDataSetProperties(info, context); } //Rows for (int i = 0; i < Tables.Count; i++) { Tables[i].SerializeTableData(info, context, i); } } else { // old behaviour String strSchema = this.GetXmlSchemaForRemoting(null); String strData = null; info.AddValue(KEY_XMLSCHEMA, strSchema); StringBuilder strBuilder; strBuilder = new StringBuilder(EstimatedXmlStringSize() * 2); StringWriter strWriter = new StringWriter(strBuilder, CultureInfo.InvariantCulture); XmlTextWriter w = new XmlTextWriter(strWriter); WriteXml(w, XmlWriteMode.DiffGram); strData = strWriter.ToString(); info.AddValue(KEY_XMLDIFFGRAM, strData); } } // Deserialize all the tables - marked internal so that DataTable can call into this internal void DeserializeDataSet(SerializationInfo info, StreamingContext context, SerializationFormat remotingFormat, SchemaSerializationMode schemaSerializationMode) { // deserialize schema DeserializeDataSetSchema(info, context, remotingFormat, schemaSerializationMode); // deserialize data DeserializeDataSetData(info, context, remotingFormat); } // Deserialize schema. private void DeserializeDataSetSchema(SerializationInfo info, StreamingContext context, SerializationFormat remotingFormat, SchemaSerializationMode schemaSerializationMode) { if (remotingFormat != SerializationFormat.Xml) { if (schemaSerializationMode == SchemaSerializationMode.IncludeSchema) { //DataSet public state properties DeserializeDataSetProperties(info, context); //Tables Count int tableCount = info.GetInt32("DataSet.Tables.Count"); //Tables, Columns, Rows for (int i = 0; i < tableCount; i++) { Byte[] buffer = (Byte[])info.GetValue(String.Format(CultureInfo.InvariantCulture, "DataSet.Tables_{0}", i), typeof(Byte[])); MemoryStream memStream = new MemoryStream(buffer); memStream.Position = 0; BinaryFormatter bf = new BinaryFormatter(null, new StreamingContext(context.State, false)); DataTable dt = (DataTable)bf.Deserialize(memStream); Tables.Add(dt); } //Constraints for (int i = 0; i < tableCount; i++) { Tables[i].DeserializeConstraints(info, context, /* table index */i, /* serialize all constraints */ true); // } //Relations DeserializeRelations(info, context); //Expression Columns for (int i = 0; i < tableCount; i++) { Tables[i].DeserializeExpressionColumns(info, context, i); } } else { //DeSerialize DataSet public properties.[Locale, CaseSensitive and EnforceConstraints] DeserializeDataSetProperties(info, context); } } else { string strSchema = (String)info.GetValue(KEY_XMLSCHEMA, typeof(System.String)); if (strSchema != null) { this.ReadXmlSchema(new XmlTextReader(new StringReader(strSchema)), true); } } } // Deserialize all data. private void DeserializeDataSetData(SerializationInfo info, StreamingContext context, SerializationFormat remotingFormat) { if (remotingFormat != SerializationFormat.Xml) { for (int i = 0; i < Tables.Count; i++) { Tables[i].DeserializeTableData(info, context, i); } } else { string strData = (String)info.GetValue(KEY_XMLDIFFGRAM, typeof(System.String)); if (strData != null) { this.ReadXml(new XmlTextReader(new StringReader(strData)), XmlReadMode.DiffGram); } } } // Serialize just the dataset properties private void SerializeDataSetProperties(SerializationInfo info, StreamingContext context) { //DataSet basic properties info.AddValue("DataSet.DataSetName", DataSetName); info.AddValue("DataSet.Namespace", Namespace); info.AddValue("DataSet.Prefix", Prefix); //DataSet runtime properties info.AddValue("DataSet.CaseSensitive", CaseSensitive); info.AddValue("DataSet.LocaleLCID", Locale.LCID); info.AddValue("DataSet.EnforceConstraints", EnforceConstraints); //ExtendedProperties info.AddValue("DataSet.ExtendedProperties", ExtendedProperties); } // DeSerialize dataset properties private void DeserializeDataSetProperties(SerializationInfo info, StreamingContext context) { //DataSet basic properties dataSetName = info.GetString("DataSet.DataSetName"); namespaceURI = info.GetString("DataSet.Namespace"); _datasetPrefix = info.GetString("DataSet.Prefix"); //DataSet runtime properties _caseSensitive = info.GetBoolean("DataSet.CaseSensitive"); int lcid = (int)info.GetValue("DataSet.LocaleLCID", typeof(int)); _culture = new CultureInfo(lcid); _cultureUserSet = true; enforceConstraints = info.GetBoolean("DataSet.EnforceConstraints"); //ExtendedProperties extendedProperties = (PropertyCollection)info.GetValue("DataSet.ExtendedProperties", typeof(PropertyCollection)); } // Gets relation info from the dataset. // ***Schema for Serializing ArrayList of Relations*** // Relations -> [relationName]->[parentTableIndex, parentcolumnIndexes]->[childTableIndex, childColumnIndexes]->[Nested]->[extendedProperties] private void SerializeRelations(SerializationInfo info, StreamingContext context) { ArrayList relationList = new ArrayList(); foreach (DataRelation rel in Relations) { int[] parentInfo = new int[rel.ParentColumns.Length + 1]; parentInfo[0] = Tables.IndexOf(rel.ParentTable); for (int j = 1; j < parentInfo.Length; j++) { parentInfo[j] = rel.ParentColumns[j - 1].Ordinal; } int[] childInfo = new int[rel.ChildColumns.Length + 1]; childInfo[0] = Tables.IndexOf(rel.ChildTable); for (int j = 1; j < childInfo.Length; j++) { childInfo[j] = rel.ChildColumns[j - 1].Ordinal; } ArrayList list = new ArrayList(); list.Add(rel.RelationName); list.Add(parentInfo); list.Add(childInfo); list.Add(rel.Nested); list.Add(rel.extendedProperties); relationList.Add(list); } info.AddValue("DataSet.Relations", relationList); } /* Adds relations to the dataset. ***Schema for Serializing ArrayList of Relations*** Relations -> [relationName]->[parentTableIndex, parentcolumnIndexes]->[childTableIndex, childColumnIndexes]->[Nested]->[extendedProperties] */ private void DeserializeRelations(SerializationInfo info, StreamingContext context) { ArrayList relationList = (ArrayList)info.GetValue("DataSet.Relations", typeof(ArrayList)); foreach (ArrayList list in relationList) { string relationName = (string)list[0]; int[] parentInfo = (int[])list[1]; int[] childInfo = (int[])list[2]; bool isNested = (bool)list[3]; PropertyCollection extendedProperties = (PropertyCollection)list[4]; //ParentKey Columns. DataColumn[] parentkeyColumns = new DataColumn[parentInfo.Length - 1]; for (int i = 0; i < parentkeyColumns.Length; i++) { parentkeyColumns[i] = Tables[parentInfo[0]].Columns[parentInfo[i + 1]]; } //ChildKey Columns. DataColumn[] childkeyColumns = new DataColumn[childInfo.Length - 1]; for (int i = 0; i < childkeyColumns.Length; i++) { childkeyColumns[i] = Tables[childInfo[0]].Columns[childInfo[i + 1]]; } //Create the Relation, without any constraints[Assumption: The constraints are added earlier than the relations] DataRelation rel = new DataRelation(relationName, parentkeyColumns, childkeyColumns, false); rel.CheckMultipleNested = false; // disable the check for multiple nested parent rel.Nested = isNested; rel.extendedProperties = extendedProperties; Relations.Add(rel); rel.CheckMultipleNested = true; // enable the check for multiple nested parent } } internal void FailedEnableConstraints() { this.EnforceConstraints = false; throw ExceptionBuilder.EnforceConstraint(); } /// /// /// Gets or sets a value indicating whether string /// comparisons within /// objects are /// case-sensitive. /// /// [ ResCategoryAttribute(Res.DataCategory_Data), DefaultValue(false), ResDescriptionAttribute(Res.DataSetCaseSensitiveDescr) ] public bool CaseSensitive { get { return _caseSensitive; } set { if (_caseSensitive != value) { bool oldValue = _caseSensitive; _caseSensitive = value; if (!ValidateCaseConstraint()) { _caseSensitive = oldValue; throw ExceptionBuilder.CannotChangeCaseLocale(); } foreach (DataTable table in Tables) { table.SetCaseSensitiveValue(value, false, true); } } } } bool System.ComponentModel.IListSource.ContainsListCollection { get { return true; } } /// /// Gets a custom view of the data contained by the , one /// that allows filtering, searching, and navigating through the custom data view. /// [Browsable(false), ResDescriptionAttribute(Res.DataSetDefaultViewDescr)] public DataViewManager DefaultViewManager { get { if (defaultViewManager == null) { lock (_defaultViewManagerLock) { if (defaultViewManager == null) { defaultViewManager = new DataViewManager(this, true); } } } return defaultViewManager; } } /// /// Gets or sets a value indicating whether constraint rules are followed when /// attempting any update operation. /// [DefaultValue(true), ResDescriptionAttribute(Res.DataSetEnforceConstraintsDescr)] public bool EnforceConstraints { get { return enforceConstraints; } set { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, %d{bool}\n", ObjectID, value); try { if (this.enforceConstraints != value) { if (value) EnableConstraints(); this.enforceConstraints = value; } } finally { Bid.ScopeLeave(ref hscp); } } } internal void RestoreEnforceConstraints(bool value) { this.enforceConstraints = value; } internal void EnableConstraints() { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { bool errors = false; for (ConstraintEnumerator constraints = new ConstraintEnumerator(this); constraints.GetNext(); ) { Constraint constraint = (Constraint)constraints.GetConstraint(); errors |= constraint.IsConstraintViolated(); } foreach (DataTable table in Tables) { foreach (DataColumn column in table.Columns) { if (!column.AllowDBNull) { errors |= column.IsNotAllowDBNullViolated(); } if (column.MaxLength >= 0) { errors |= column.IsMaxLengthViolated(); } } } if (errors) this.FailedEnableConstraints(); } finally { Bid.ScopeLeave(ref hscp); } } /// /// Gets or /// sets the name of this . /// [ ResCategoryAttribute(Res.DataCategory_Data), DefaultValue(""), ResDescriptionAttribute(Res.DataSetDataSetNameDescr) ] public string DataSetName { get { return dataSetName; } set { Bid.Trace(" %d#, '%ls'\n", ObjectID, value); if (value != dataSetName) { if (value == null || value.Length == 0) throw ExceptionBuilder.SetDataSetNameToEmpty(); DataTable conflicting = Tables[value, Namespace]; if ((conflicting != null) && (!conflicting.fNestedInDataset)) throw ExceptionBuilder.SetDataSetNameConflicting(value); RaisePropertyChanging("DataSetName"); this.dataSetName = value; } } } /// /// [ DefaultValue(""), ResCategoryAttribute(Res.DataCategory_Data), ResDescriptionAttribute(Res.DataSetNamespaceDescr) ] public string Namespace { get { return namespaceURI; } set { Bid.Trace(" %d#, '%ls'\n", ObjectID, value); if (value == null) value = String.Empty; if (value != namespaceURI) { RaisePropertyChanging("Namespace"); foreach (DataTable dt in Tables) { if (dt.tableNamespace != null) continue; if ((dt.NestedParentRelations.Length == 0) || (dt.NestedParentRelations.Length == 1 && dt.NestedParentRelations[0].ChildTable == dt)) { // dt.SelfNestedWithOneRelation) { // this is wrong bug it was previous behavior if (Tables.Contains(dt.TableName, value, false, true)) throw ExceptionBuilder.DuplicateTableName2(dt.TableName, value); dt.CheckCascadingNamespaceConflict(value); dt.DoRaiseNamespaceChange(); } } namespaceURI = value; if (Common.ADP.IsEmpty(value)) _datasetPrefix = String.Empty; } } } /// /// [To be supplied.] /// [ DefaultValue(""), ResCategoryAttribute(Res.DataCategory_Data), ResDescriptionAttribute(Res.DataSetPrefixDescr) ] public string Prefix { get { return _datasetPrefix; } set { if (value == null) value = String.Empty; if ((XmlConvert.DecodeName(value) == value) && (XmlConvert.EncodeName(value) != value)) throw ExceptionBuilder.InvalidPrefix(value); if (value != _datasetPrefix) { RaisePropertyChanging("Prefix"); _datasetPrefix = value; } } } /// /// Gets the collection of custom user information. /// [ ResCategoryAttribute(Res.DataCategory_Data), Browsable(false), ResDescriptionAttribute(Res.ExtendedPropertiesDescr) ] public PropertyCollection ExtendedProperties { get { if (extendedProperties == null) { extendedProperties = new PropertyCollection(); } return extendedProperties; } } /// /// /// Gets a value indicating whether there are errors in any /// of the rows in any of the tables of this . /// /// [Browsable(false), ResDescriptionAttribute(Res.DataSetHasErrorsDescr)] public bool HasErrors { get { for (int i = 0; i < Tables.Count; i++) { if (Tables[i].HasErrors) return true; } return false; } } [Browsable(false)] public bool IsInitialized { get { return !fInitInProgress; } } /// /// /// Gets or sets the locale information used to compare strings within the table. /// /// [ ResCategoryAttribute(Res.DataCategory_Data), ResDescriptionAttribute(Res.DataSetLocaleDescr) ] public CultureInfo Locale { get { // used for comparing not formating/parsing Debug.Assert(null != _culture, "DataSet.Locale: null culture"); return _culture; } set { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { if (value != null) { if (!_culture.Equals(value)) { SetLocaleValue(value, true); } _cultureUserSet = true; } } finally { Bid.ScopeLeave(ref hscp); } } } internal void SetLocaleValue(CultureInfo value, bool userSet) { bool flag = false; bool exceptionThrown = false; int tableCount = 0; CultureInfo oldLocale = _culture; bool oldUserSet = _cultureUserSet; try { _culture = value; _cultureUserSet = userSet; foreach (DataTable table in Tables) { if (!table.ShouldSerializeLocale()) { bool retchk = table.SetLocaleValue(value, false, false); //Debug.Assert(retchk == table.ShouldSerializeLocale(), "unexpected setting of table locale"); may fire with Deserialize } } flag = ValidateLocaleConstraint(); if (flag) { flag = false; foreach (DataTable table in Tables) { tableCount++; if (!table.ShouldSerializeLocale()) { table.SetLocaleValue(value, false, true); } } flag = true; } } catch { exceptionThrown = true; throw; } finally { if (!flag) { // reset old locale if ValidationFailed or exception thrown _culture = oldLocale; _cultureUserSet = oldUserSet; foreach (DataTable table in Tables) { if (!table.ShouldSerializeLocale()) { table.SetLocaleValue(oldLocale, false, false); } } try { for (int i = 0; i < tableCount; ++i) { if (!Tables[i].ShouldSerializeLocale()) { Tables[i].SetLocaleValue(oldLocale, false, true); } } } catch (Exception e) { if (!Common.ADP.IsCatchableExceptionType(e)) { throw; } Common.ADP.TraceExceptionWithoutRethrow(e); } if (!exceptionThrown) { throw ExceptionBuilder.CannotChangeCaseLocale(null); } } } } internal bool ShouldSerializeLocale() { // this method is used design-time scenarios via reflection // by the property grid to show the Locale property in bold or not // by the code dom for persisting the Locale property or not // we always want the locale persisted if set by user or different the current thread // but that logic should by performed by the serializion code return _cultureUserSet; } /// /// [To be supplied.] /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public override ISite Site { get { return base.Site; } set { ISite oldSite = Site; if (value == null && oldSite != null) { IContainer cont = oldSite.Container; if (cont != null) { for (int i = 0; i < Tables.Count; i++) { if (Tables[i].Site != null) { cont.Remove(Tables[i]); } } } } base.Site = value; } } /// /// /// Get the collection of relations that link tables and /// allow navigation from parent tables to child tables. /// /// [ DesignerSerializationVisibility(DesignerSerializationVisibility.Content), ResCategoryAttribute(Res.DataCategory_Data), ResDescriptionAttribute(Res.DataSetRelationsDescr) ] public DataRelationCollection Relations { get { return relationCollection; } } /// /// /// Indicates whether property should be persisted. /// /// protected virtual bool ShouldSerializeRelations() { return true; /*Relations.Count > 0;*/ // VS7 300569 } /// /// /// Resets the property to its default state. /// /// private void ResetRelations() { Relations.Clear(); } /// /// Gets the collection of tables contained in the . /// [ DesignerSerializationVisibility(DesignerSerializationVisibility.Content), ResCategoryAttribute(Res.DataCategory_Data), ResDescriptionAttribute(Res.DataSetTablesDescr) ] public DataTableCollection Tables { get { return tableCollection; } } /// /// /// Indicates whether property should be persisted. /// /// protected virtual bool ShouldSerializeTables() { return true;/*(Tables.Count > 0);*/ // VS7 300569 } /// /// /// Resets the property to its default state. /// /// private void ResetTables() { Tables.Clear(); } internal bool FBoundToDocument { get { return fBoundToDocument; } set { fBoundToDocument = value; } } /// /// /// Commits all the changes made to this since it was loaded or the last /// time was called. /// /// public void AcceptChanges() { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { for (int i = 0; i < Tables.Count; i++) Tables[i].AcceptChanges(); } finally { Bid.ScopeLeave(ref hscp); } } internal event PropertyChangedEventHandler PropertyChanging { add { onPropertyChangingDelegate += value; } remove { onPropertyChangingDelegate -= value; } } /// /// Occurs when attempting to merge schemas for two tables with the same /// name. /// [ ResCategoryAttribute(Res.DataCategory_Action), ResDescriptionAttribute(Res.DataSetMergeFailedDescr) ] public event MergeFailedEventHandler MergeFailed { add { onMergeFailed += value; } remove { onMergeFailed -= value; } } internal event DataRowCreatedEventHandler DataRowCreated { add { onDataRowCreated += value; } remove { onDataRowCreated -= value; } } internal event DataSetClearEventhandler ClearFunctionCalled { add { onClearFunctionCalled += value; } remove { onClearFunctionCalled -= value; } } [ ResCategoryAttribute(Res.DataCategory_Action), ResDescriptionAttribute(Res.DataSetInitializedDescr) ] public event System.EventHandler Initialized { add { onInitialized += value; } remove { onInitialized -= value; } } public void BeginInit() { fInitInProgress = true; } public void EndInit() { Tables.FinishInitCollection(); for (int i = 0; i < Tables.Count; i++) { Tables[i].Columns.FinishInitCollection(); } for (int i = 0; i < Tables.Count; i++) { Tables[i].Constraints.FinishInitConstraints(); } ((DataRelationCollection.DataSetRelationCollection)Relations).FinishInitRelations(); fInitInProgress = false; OnInitialized(); } /// /// Clears the of any data by removing all rows in all tables. /// public void Clear() { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { OnClearFunctionCalled(null); bool fEnforce = EnforceConstraints; EnforceConstraints = false; for (int i = 0; i < Tables.Count; i++) Tables[i].Clear(); EnforceConstraints = fEnforce; } finally { Bid.ScopeLeave(ref hscp); } } /// /// Clones the structure of the , including all schemas, relations, and /// constraints. /// // Prevent inlining so that reflection calls are not moved to caller that may be in a different assembly that may have a different grant set. [MethodImpl(MethodImplOptions.NoInlining)] public virtual DataSet Clone() { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { DataSet ds = (DataSet)Activator.CreateInstance(this.GetType(), true); if (ds.Tables.Count > 0) // [....] : To clean up all the schema in strong typed dataset. ds.Reset(); //copy some original dataset properties ds.DataSetName = DataSetName; ds.CaseSensitive = CaseSensitive; ds._culture = _culture; ds._cultureUserSet = _cultureUserSet; ds.EnforceConstraints = EnforceConstraints; ds.Namespace = Namespace; ds.Prefix = Prefix; ds.RemotingFormat = RemotingFormat; ds.fIsSchemaLoading = true; //delay expression evaluation // ...Tables... DataTableCollection tbls = Tables; for (int i = 0; i < tbls.Count; i++) { DataTable dt = tbls[i].Clone(ds); dt.tableNamespace = tbls[i].Namespace; // hardcode the namespace for a second to not mess up // DataRelation cloning. ds.Tables.Add(dt); } // ...Constraints... for (int i = 0; i < tbls.Count; i++) { ConstraintCollection constraints = tbls[i].Constraints; for (int j = 0; j < constraints.Count; j++) { if (constraints[j] is UniqueConstraint) continue; ForeignKeyConstraint foreign = constraints[j] as ForeignKeyConstraint; if (foreign.Table == foreign.RelatedTable) continue;// we have already added this foreign key in while cloning the datatable ds.Tables[i].Constraints.Add(constraints[j].Clone(ds)); } } // ...Relations... DataRelationCollection rels = Relations; for (int i = 0; i < rels.Count; i++) { DataRelation rel = rels[i].Clone(ds); rel.CheckMultipleNested = false; // disable the check for multiple nested parent ds.Relations.Add(rel); rel.CheckMultipleNested = true; // enable the check for multiple nested parent } // ...Extended Properties... if (this.extendedProperties != null) { foreach (Object key in this.extendedProperties.Keys) { ds.ExtendedProperties[key] = this.extendedProperties[key]; } } foreach (DataTable table in Tables) foreach (DataColumn col in table.Columns) if (col.Expression.Length != 0) ds.Tables[table.TableName, table.Namespace].Columns[col.ColumnName].Expression = col.Expression; for (int i = 0; i < tbls.Count; i++) { ds.Tables[i].tableNamespace = tbls[i].tableNamespace; // undo the hardcoding of the namespace } ds.fIsSchemaLoading = false; //reactivate column computations return ds; } finally { Bid.ScopeLeave(ref hscp); } } /// /// Copies both the structure and data for this . /// public DataSet Copy() { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { DataSet dsNew = Clone(); bool fEnforceConstraints = dsNew.EnforceConstraints; dsNew.EnforceConstraints = false; foreach (DataTable table in this.Tables) { DataTable destTable = dsNew.Tables[table.TableName, table.Namespace]; foreach (DataRow row in table.Rows) table.CopyRow(destTable, row); } dsNew.EnforceConstraints = fEnforceConstraints; return dsNew; } finally { Bid.ScopeLeave(ref hscp); } } internal Int32 EstimatedXmlStringSize() { Int32 bytes = 100; for (int i = 0; i < Tables.Count; i++) { Int32 rowBytes = (Tables[i].TableName.Length + 4) << 2; DataTable table = Tables[i]; for (int j = 0; j < table.Columns.Count; j++) { rowBytes += ((table.Columns[j].ColumnName.Length + 4) << 2); rowBytes += 20; } bytes += table.Rows.Count * rowBytes; } return bytes; } /// /// Returns a copy of the that contains all changes made to /// it since it was loaded or /// was last called. /// public DataSet GetChanges() { return GetChanges(DataRowState.Added | DataRowState.Deleted | DataRowState.Modified); } private struct TableChanges { private BitArray _rowChanges; private int _hasChanges; internal TableChanges(int rowCount) { _rowChanges = new BitArray(rowCount); _hasChanges = 0; } internal int HasChanges { get { return _hasChanges; } set { _hasChanges = value; } } internal bool this[int index] { get { return _rowChanges[index]; } set { Debug.Assert(value && !_rowChanges[index], "setting twice or to false"); _rowChanges[index] = value; _hasChanges++; } } } public DataSet GetChanges(DataRowState rowStates) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, rowStates=%d{ds.DataRowState}\n", ObjectID, (int)rowStates); try { DataSet dsNew = null; bool fEnforceConstraints = false; if (0 != (rowStates & ~(DataRowState.Added | DataRowState.Deleted | DataRowState.Modified | DataRowState.Unchanged))) { throw ExceptionBuilder.InvalidRowState(rowStates); } // Initialize all the individual table bitmaps. TableChanges[] bitMatrix = new TableChanges[Tables.Count]; for (int i = 0; i < bitMatrix.Length; ++i) { bitMatrix[i] = new TableChanges(Tables[i].Rows.Count); } // find all the modified rows and their parents MarkModifiedRows(bitMatrix, rowStates); // copy the changes to a cloned table for (int i = 0; i < bitMatrix.Length; ++i) { Debug.Assert(0 <= bitMatrix[i].HasChanges, "negative change count"); if (0 < bitMatrix[i].HasChanges) { if (null == dsNew) { dsNew = this.Clone(); fEnforceConstraints = dsNew.EnforceConstraints; dsNew.EnforceConstraints = false; } DataTable table = this.Tables[i]; DataTable destTable = dsNew.Tables[table.TableName, table.Namespace]; Debug.Assert(bitMatrix[i].HasChanges <= table.Rows.Count, "to many changes"); for (int j = 0; 0 < bitMatrix[i].HasChanges; ++j) { // Loop through the rows. if (bitMatrix[i][j]) { table.CopyRow(destTable, table.Rows[j]); bitMatrix[i].HasChanges--; } } } } if (null != dsNew) { dsNew.EnforceConstraints = fEnforceConstraints; } return dsNew; } finally { Bid.ScopeLeave(ref hscp); } } private void MarkModifiedRows(TableChanges[] bitMatrix, DataRowState rowStates) { // for every table, every row & every relation find the modified rows and for non-deleted rows, their parents for (int tableIndex = 0; tableIndex < bitMatrix.Length; ++tableIndex) { DataRowCollection rows = Tables[tableIndex].Rows; int rowCount = rows.Count; for (int rowIndex = 0; rowIndex < rowCount; ++rowIndex) { DataRow row = rows[rowIndex]; DataRowState rowState = row.RowState; Debug.Assert(DataRowState.Added == rowState || DataRowState.Deleted == rowState || DataRowState.Modified == rowState || DataRowState.Unchanged == rowState, "unexpected DataRowState"); // if bit not already set and row is modified if ((0 != (rowStates & rowState)) && !bitMatrix[tableIndex][rowIndex]) { bitMatrix[tableIndex][rowIndex] = true; if (DataRowState.Deleted != rowState) { MarkRelatedRowsAsModified(bitMatrix, row); } } } } } private void MarkRelatedRowsAsModified(TableChanges[] bitMatrix, DataRow row) { DataRelationCollection relations = row.Table.ParentRelations; int relationCount = relations.Count; for (int relatedIndex = 0; relatedIndex < relationCount; ++relatedIndex) { DataRow[] relatedRows = row.GetParentRows(relations[relatedIndex], DataRowVersion.Current); foreach (DataRow relatedRow in relatedRows) { int relatedTableIndex = this.Tables.IndexOf(relatedRow.Table); int relatedRowIndex = relatedRow.Table.Rows.IndexOf(relatedRow); if (!bitMatrix[relatedTableIndex][relatedRowIndex]) { bitMatrix[relatedTableIndex][relatedRowIndex] = true; if (DataRowState.Deleted != relatedRow.RowState) { // recurse into related rows MarkRelatedRowsAsModified(bitMatrix, relatedRow); } } } } } IList System.ComponentModel.IListSource.GetList() { return DefaultViewManager; } internal string GetRemotingDiffGram(DataTable table) { StringWriter strWriter = new StringWriter(CultureInfo.InvariantCulture); XmlTextWriter writer = new XmlTextWriter(strWriter); writer.Formatting = Formatting.Indented; if (strWriter != null) { // Create and save the updates new NewDiffgramGen(table, false).Save(writer, table); } return strWriter.ToString(); } public string GetXml() { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { // StringBuilder strBuilder = new StringBuilder(EstimatedXmlStringSize()); // StringWriter strWriter = new StringWriter(strBuilder); StringWriter strWriter = new StringWriter(CultureInfo.InvariantCulture); if (strWriter != null) { XmlTextWriter w = new XmlTextWriter(strWriter); w.Formatting = Formatting.Indented; new XmlDataTreeWriter(this).Save(w, false); } return strWriter.ToString(); } finally { Bid.ScopeLeave(ref hscp); } } public string GetXmlSchema() { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { StringWriter strWriter = new StringWriter(CultureInfo.InvariantCulture); XmlTextWriter writer = new XmlTextWriter(strWriter); writer.Formatting = Formatting.Indented; if (strWriter != null) { (new XmlTreeGen(SchemaFormat.Public)).Save(this, writer); } return strWriter.ToString(); } finally { Bid.ScopeLeave(ref hscp); } } internal string GetXmlSchemaForRemoting(DataTable table) { StringWriter strWriter = new StringWriter(CultureInfo.InvariantCulture); XmlTextWriter writer = new XmlTextWriter(strWriter); writer.Formatting = Formatting.Indented; if (strWriter != null) { if (table == null) { if (this.SchemaSerializationMode == SchemaSerializationMode.ExcludeSchema) (new XmlTreeGen(SchemaFormat.RemotingSkipSchema)).Save(this, writer); else (new XmlTreeGen(SchemaFormat.Remoting)).Save(this, writer); } else { // no skip schema support for typed datatable (new XmlTreeGen(SchemaFormat.Remoting)).Save(table, writer); } } return strWriter.ToString(); } /// /// Gets a value indicating whether the has changes, including new, /// deleted, or modified rows. /// public bool HasChanges() { return HasChanges(DataRowState.Added | DataRowState.Deleted | DataRowState.Modified); } /// /// Gets a value indicating whether the has changes, including new, /// deleted, or modified rows, filtered by . /// public bool HasChanges(DataRowState rowStates) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, rowStates=%d{ds.DataRowState}\n", ObjectID, (int)rowStates); try { const DataRowState allRowStates = DataRowState.Detached | DataRowState.Unchanged | DataRowState.Added | DataRowState.Deleted | DataRowState.Modified; if ((rowStates & (~allRowStates)) != 0) { throw ExceptionBuilder.ArgumentOutOfRange("rowState"); } for (int i = 0; i < Tables.Count; i++) { DataTable table = Tables[i]; for (int j = 0; j < table.Rows.Count; j++) { DataRow row = table.Rows[j]; if ((row.RowState & rowStates) != 0) { return true; } } } return false; } finally { Bid.ScopeLeave(ref hscp); } } /// /// Infer the XML schema from the specified into the . /// public void InferXmlSchema(XmlReader reader, string[] nsArray) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { if (reader == null) return; XmlDocument xdoc = new XmlDocument(); if (reader.NodeType == XmlNodeType.Element) { XmlNode node = xdoc.ReadNode(reader); xdoc.AppendChild(node); } else xdoc.Load(reader); if (xdoc.DocumentElement == null) return; InferSchema(xdoc, nsArray, XmlReadMode.InferSchema); } finally { Bid.ScopeLeave(ref hscp); } } /// /// Infer the XML schema from the specified into the . /// public void InferXmlSchema(Stream stream, string[] nsArray) { if (stream == null) return; InferXmlSchema(new XmlTextReader(stream), nsArray); } /// /// Infer the XML schema from the specified into the . /// public void InferXmlSchema(TextReader reader, string[] nsArray) { if (reader == null) return; InferXmlSchema(new XmlTextReader(reader), nsArray); } /// /// Infer the XML schema from the specified file into the . /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void InferXmlSchema(String fileName, string[] nsArray) { XmlTextReader xr = new XmlTextReader(fileName); try { InferXmlSchema(xr, nsArray); } finally { xr.Close(); } } /// /// Reads the XML schema from the specified into the /// . /// public void ReadXmlSchema(XmlReader reader) { ReadXmlSchema(reader, false); } internal void ReadXmlSchema(XmlReader reader, bool denyResolving) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, reader, denyResolving=%d{bool}\n", ObjectID, denyResolving); try { int iCurrentDepth = -1; if (reader == null) return; if (reader is XmlTextReader) ((XmlTextReader)reader).WhitespaceHandling = WhitespaceHandling.None; XmlDocument xdoc = new XmlDocument(); // we may need this to infer the schema if (reader.NodeType == XmlNodeType.Element) iCurrentDepth = reader.Depth; reader.MoveToContent(); if (reader.NodeType == XmlNodeType.Element) { // if reader points to the schema load it... if (reader.LocalName == Keywords.XDR_SCHEMA && reader.NamespaceURI == Keywords.XDRNS) { // load XDR schema and exit ReadXDRSchema(reader); return; } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI == Keywords.XSDNS) { // load XSD schema and exit ReadXSDSchema(reader, denyResolving); return; } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI.StartsWith(Keywords.XSD_NS_START, StringComparison.Ordinal)) throw ExceptionBuilder.DataSetUnsupportedSchema(Keywords.XSDNS); // ... otherwise backup the top node and all its attributes XmlElement topNode = xdoc.CreateElement(reader.Prefix, reader.LocalName, reader.NamespaceURI); if (reader.HasAttributes) { int attrCount = reader.AttributeCount; for (int i = 0; i < attrCount; i++) { reader.MoveToAttribute(i); if (reader.NamespaceURI.Equals(Keywords.XSD_XMLNS_NS)) topNode.SetAttribute(reader.Name, reader.GetAttribute(i)); else { XmlAttribute attr = topNode.SetAttributeNode(reader.LocalName, reader.NamespaceURI); attr.Prefix = reader.Prefix; attr.Value = reader.GetAttribute(i); } } } reader.Read(); while (MoveToElement(reader, iCurrentDepth)) { // if reader points to the schema load it... if (reader.LocalName == Keywords.XDR_SCHEMA && reader.NamespaceURI == Keywords.XDRNS) { // load XDR schema and exit ReadXDRSchema(reader); return; } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI == Keywords.XSDNS) { // load XSD schema and exit ReadXSDSchema(reader, denyResolving); return; } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI.StartsWith(Keywords.XSD_NS_START, StringComparison.Ordinal)) throw ExceptionBuilder.DataSetUnsupportedSchema(Keywords.XSDNS); XmlNode node = xdoc.ReadNode(reader); topNode.AppendChild(node); } // read the closing tag of the current element ReadEndElement(reader); // if we are here no schema has been found xdoc.AppendChild(topNode); // so we InferSchema InferSchema(xdoc, null, XmlReadMode.Auto); } } finally { Bid.ScopeLeave(ref hscp); } } internal bool MoveToElement(XmlReader reader, int depth) { while (!reader.EOF && reader.NodeType != XmlNodeType.EndElement && reader.NodeType != XmlNodeType.Element && reader.Depth > depth) { reader.Read(); } return (reader.NodeType == XmlNodeType.Element); } private static void MoveToElement(XmlReader reader) { while (!reader.EOF && reader.NodeType != XmlNodeType.EndElement && reader.NodeType != XmlNodeType.Element) { reader.Read(); } } internal void ReadEndElement(XmlReader reader) { while (reader.NodeType == XmlNodeType.Whitespace) { reader.Skip(); } if (reader.NodeType == XmlNodeType.None) { reader.Skip(); } else if (reader.NodeType == XmlNodeType.EndElement) { reader.ReadEndElement(); } } internal void ReadXSDSchema(XmlReader reader, bool denyResolving) { XmlSchemaSet sSet = new XmlSchemaSet(); int schemaFragmentCount = 1; //read from current schmema element if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI == Keywords.XSDNS) { if (reader.HasAttributes) { string attribValue = reader.GetAttribute(Keywords.MSD_FRAGMENTCOUNT, Keywords.MSDNS); // this must not move the position if (!Common.ADP.IsEmpty(attribValue)) { schemaFragmentCount = int.Parse(attribValue, null); } } } while (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI == Keywords.XSDNS) { XmlSchema s = XmlSchema.Read(reader, null); sSet.Add(s); //read the end tag ReadEndElement(reader); if (--schemaFragmentCount > 0) { MoveToElement(reader); } while (reader.NodeType == XmlNodeType.Whitespace) { reader.Skip(); } } sSet.Compile(); XSDSchema schema = new XSDSchema(); schema.LoadSchema(sSet, this); } internal void ReadXDRSchema(XmlReader reader) { XmlDocument xdoc = new XmlDocument(); // we may need this to infer the schema XmlNode schNode = xdoc.ReadNode(reader); xdoc.AppendChild(schNode); XDRSchema schema = new XDRSchema(this, false); this.DataSetName = xdoc.DocumentElement.LocalName; schema.LoadSchema((XmlElement)schNode, this); } /// /// Reads the XML schema from the specified into the /// . /// public void ReadXmlSchema(Stream stream) { if (stream == null) return; ReadXmlSchema(new XmlTextReader(stream), false); } /// /// Reads the XML schema from the specified into the . /// public void ReadXmlSchema(TextReader reader) { if (reader == null) return; ReadXmlSchema(new XmlTextReader(reader), false); } /// /// Reads the XML schema from the specified file into the . /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void ReadXmlSchema(String fileName) { XmlTextReader xr = new XmlTextReader(fileName); try { ReadXmlSchema(xr, false); } finally { xr.Close(); } } #region WriteXmlSchema /// Writes the structure as an XML schema to using the specified object. /// A object used to write to a file. public void WriteXmlSchema(Stream stream) { this.WriteXmlSchema(stream, SchemaFormat.Public, (Converter)null); } /// Writes the structure as an XML schema to using the specified object. /// A object used to write to a file. /// A delegate used to convert into string. public void WriteXmlSchema(Stream stream, Converter multipleTargetConverter) { ADP.CheckArgumentNull(multipleTargetConverter, "multipleTargetConverter"); this.WriteXmlSchema(stream, SchemaFormat.Public, multipleTargetConverter); } /// Writes the structure as an XML schema to a file. /// The file name (including the path) to which to write. [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void WriteXmlSchema(String fileName) { this.WriteXmlSchema(fileName, SchemaFormat.Public, (Converter)null); } /// Writes the structure as an XML schema to a file. /// The file name (including the path) to which to write. /// A delegate used to convert into string. [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void WriteXmlSchema(String fileName, Converter multipleTargetConverter) { ADP.CheckArgumentNull(multipleTargetConverter, "multipleTargetConverter"); this.WriteXmlSchema(fileName, SchemaFormat.Public, multipleTargetConverter); } /// Writes the structure as an XML schema to a object. /// The object with which to write. public void WriteXmlSchema(TextWriter writer) { this.WriteXmlSchema(writer, SchemaFormat.Public, (Converter)null); } /// Writes the structure as an XML schema to a object. /// The object with which to write. /// A delegate used to convert into string. public void WriteXmlSchema(TextWriter writer, Converter multipleTargetConverter) { ADP.CheckArgumentNull(multipleTargetConverter, "multipleTargetConverter"); this.WriteXmlSchema(writer, SchemaFormat.Public, multipleTargetConverter); } /// Writes the structure as an XML schema to an object. /// The object with which to write. public void WriteXmlSchema(XmlWriter writer) { this.WriteXmlSchema(writer, SchemaFormat.Public, (Converter)null); } /// Writes the structure as an XML schema to an object. /// The object with which to write. /// A delegate used to convert into string. public void WriteXmlSchema(XmlWriter writer, Converter multipleTargetConverter) { ADP.CheckArgumentNull(multipleTargetConverter, "multipleTargetConverter"); this.WriteXmlSchema(writer, SchemaFormat.Public, multipleTargetConverter); } [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] private void WriteXmlSchema(String fileName, SchemaFormat schemaFormat, Converter multipleTargetConverter) { XmlTextWriter xw = new XmlTextWriter( fileName, null ); try { xw.Formatting = Formatting.Indented; xw.WriteStartDocument(true); this.WriteXmlSchema(xw, schemaFormat, multipleTargetConverter); xw.WriteEndDocument(); } finally { xw.Close(); } } private void WriteXmlSchema(Stream stream, SchemaFormat schemaFormat, Converter multipleTargetConverter) { if (stream == null) return; XmlTextWriter w = new XmlTextWriter(stream, null); w.Formatting = Formatting.Indented; this.WriteXmlSchema(w, schemaFormat, multipleTargetConverter); } private void WriteXmlSchema(TextWriter writer, SchemaFormat schemaFormat, Converter multipleTargetConverter) { if (writer == null) return; XmlTextWriter w = new XmlTextWriter(writer); w.Formatting = Formatting.Indented; this.WriteXmlSchema(w, schemaFormat, multipleTargetConverter); } private void WriteXmlSchema(XmlWriter writer, SchemaFormat schemaFormat, Converter multipleTargetConverter) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, schemaFormat=%d{ds.SchemaFormat}\n", ObjectID, (int)schemaFormat); try { // Generate SchemaTree and write it out if (writer != null) { XmlTreeGen treeGen = null; if (schemaFormat == SchemaFormat.WebService && SchemaSerializationMode == SchemaSerializationMode.ExcludeSchema && writer.WriteState == WriteState.Element) { treeGen = new XmlTreeGen(SchemaFormat.WebServiceSkipSchema); } else { treeGen = new XmlTreeGen(schemaFormat); } treeGen.Save(this, (DataTable)null, writer, false, multipleTargetConverter); } } finally { Bid.ScopeLeave(ref hscp); } } #endregion /// /// public XmlReadMode ReadXml(XmlReader reader) { return ReadXml(reader, false); } internal XmlReadMode ReadXml(XmlReader reader, bool denyResolving) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, denyResolving=%d{bool}\n", ObjectID, denyResolving); try { DataTable.DSRowDiffIdUsageSection rowDiffIdUsage = new DataTable.DSRowDiffIdUsageSection(); try { bool fDataFound = false; bool fSchemaFound = false; bool fDiffsFound = false; bool fIsXdr = false; int iCurrentDepth = -1; XmlReadMode ret = XmlReadMode.Auto; bool isEmptyDataSet = false; bool topNodeIsProcessed = false; // we chanche topnode and there is just one case that we miss to process it // it is : txt // clear the hashtable to avoid conflicts between diffgrams, SqlHotFix 782 rowDiffIdUsage.Prepare(this); if (reader == null) return ret; if (Tables.Count == 0) { isEmptyDataSet = true; } if (reader is XmlTextReader) ((XmlTextReader)reader).WhitespaceHandling = WhitespaceHandling.Significant; XmlDocument xdoc = new XmlDocument(); // we may need this to infer the schema XmlDataLoader xmlload = null; reader.MoveToContent(); if (reader.NodeType == XmlNodeType.Element) iCurrentDepth = reader.Depth; if (reader.NodeType == XmlNodeType.Element) { if ((reader.LocalName == Keywords.DIFFGRAM) && (reader.NamespaceURI == Keywords.DFFNS)) { this.ReadXmlDiffgram(reader); // read the closing tag of the current element ReadEndElement(reader); return XmlReadMode.DiffGram; } // if reader points to the schema load it if (reader.LocalName == Keywords.XDR_SCHEMA && reader.NamespaceURI == Keywords.XDRNS) { // load XDR schema and exit ReadXDRSchema(reader); return XmlReadMode.ReadSchema; //since the top level element is a schema return } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI == Keywords.XSDNS) { // load XSD schema and exit ReadXSDSchema(reader, denyResolving); return XmlReadMode.ReadSchema; //since the top level element is a schema return } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI.StartsWith(Keywords.XSD_NS_START, StringComparison.Ordinal)) throw ExceptionBuilder.DataSetUnsupportedSchema(Keywords.XSDNS); // now either the top level node is a table and we load it through dataReader... // ... or backup the top node and all its attributes because we may need to InferSchema XmlElement topNode = xdoc.CreateElement(reader.Prefix, reader.LocalName, reader.NamespaceURI); if (reader.HasAttributes) { int attrCount = reader.AttributeCount; for (int i = 0; i < attrCount; i++) { reader.MoveToAttribute(i); if (reader.NamespaceURI.Equals(Keywords.XSD_XMLNS_NS)) topNode.SetAttribute(reader.Name, reader.GetAttribute(i)); else { XmlAttribute attr = topNode.SetAttributeNode(reader.LocalName, reader.NamespaceURI); attr.Prefix = reader.Prefix; attr.Value = reader.GetAttribute(i); } } } reader.Read(); string rootNodeSimpleContent = reader.Value; while (MoveToElement(reader, iCurrentDepth)) { if ((reader.LocalName == Keywords.DIFFGRAM) && (reader.NamespaceURI == Keywords.DFFNS)) { this.ReadXmlDiffgram(reader); // read the closing tag of the current element // YUKON FIX ReadEndElement(reader); // return XmlReadMode.DiffGram; ret = XmlReadMode.DiffGram; // continue reading for multiple schemas } // if reader points to the schema load it... if (!fSchemaFound && !fDataFound && reader.LocalName == Keywords.XDR_SCHEMA && reader.NamespaceURI == Keywords.XDRNS) { // load XDR schema and exit ReadXDRSchema(reader); fSchemaFound = true; fIsXdr = true; continue; } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI == Keywords.XSDNS) { // load XSD schema and exit ReadXSDSchema(reader, denyResolving); fSchemaFound = true; continue; } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI.StartsWith(Keywords.XSD_NS_START, StringComparison.Ordinal)) throw ExceptionBuilder.DataSetUnsupportedSchema(Keywords.XSDNS); if ((reader.LocalName == Keywords.DIFFGRAM) && (reader.NamespaceURI == Keywords.DFFNS)) { this.ReadXmlDiffgram(reader); fDiffsFound = true; ret = XmlReadMode.DiffGram; } else { // We have found data IFF the reader.NodeType == Element and reader.depth == currentDepth-1 // if reader.NodeType == whitespace, skip all white spaces. // skip processing i.e. continue if the first non-whitespace node is not of type element. while (!reader.EOF && reader.NodeType == XmlNodeType.Whitespace) reader.Read(); if (reader.NodeType != XmlNodeType.Element) continue; // we found data here fDataFound = true; if (!fSchemaFound && Tables.Count == 0) { XmlNode node = xdoc.ReadNode(reader); topNode.AppendChild(node); } else { if (xmlload == null) xmlload = new XmlDataLoader(this, fIsXdr, topNode, false); xmlload.LoadData(reader); topNodeIsProcessed = true; // we process the topnode if (fSchemaFound) ret = XmlReadMode.ReadSchema; else ret = XmlReadMode.IgnoreSchema; } } } // read the closing tag of the current element ReadEndElement(reader); bool isfTopLevelTableSet = false; bool tmpValue = this.fTopLevelTable; //While inference we ignore root elements text content if (!fSchemaFound && Tables.Count == 0 && !topNode.HasChildNodes) { //We shoule not come add SC of root elemnt to topNode if we are not infering this.fTopLevelTable = true; isfTopLevelTableSet = true; if ((rootNodeSimpleContent != null && rootNodeSimpleContent.Length > 0)) topNode.InnerText = rootNodeSimpleContent; } if (!isEmptyDataSet) { if ((rootNodeSimpleContent != null && rootNodeSimpleContent.Length > 0)) topNode.InnerText = rootNodeSimpleContent; } // now top node contains the data part xdoc.AppendChild(topNode); if (xmlload == null) xmlload = new XmlDataLoader(this, fIsXdr, topNode, false); if (!isEmptyDataSet && !topNodeIsProcessed) { XmlElement root = xdoc.DocumentElement; Debug.Assert(root.NamespaceURI != null, "root.NamespaceURI should not ne null, it should be empty string"); // just recognize that below given Xml represents datatable in toplevel //text
// only allow root element with simple content, if any if (root.ChildNodes.Count == 0 || ((root.ChildNodes.Count == 1) && root.FirstChild.GetType() == typeof(System.Xml.XmlText))) { bool initfTopLevelTable = this.fTopLevelTable; // if root element maps to a datatable // ds and dt cant have the samm name and ns at the same time, how to write to xml if (this.DataSetName != root.Name && this.namespaceURI != root.NamespaceURI && Tables.Contains(root.Name, (root.NamespaceURI.Length == 0) ? null : root.NamespaceURI, false, true)) { this.fTopLevelTable = true; } try { xmlload.LoadData(xdoc); } finally { this.fTopLevelTable = initfTopLevelTable; // this is not for inference, we have schema and we were skipping // topnode where it was a datatable, We must restore the value } } }// above check and below check are orthogonal // so we InferSchema if (!fDiffsFound) { // Load Data if (!fSchemaFound && Tables.Count == 0) { InferSchema(xdoc, null, XmlReadMode.Auto); ret = XmlReadMode.InferSchema; xmlload.FromInference = true; try { xmlload.LoadData(xdoc); } finally { xmlload.FromInference = false; } } //We dont need this assignement. Once we set it(where we set it during inference), it won't be changed if (isfTopLevelTableSet) this.fTopLevelTable = tmpValue; } } return ret; } finally { rowDiffIdUsage.Cleanup(); } } finally { Bid.ScopeLeave(ref hscp); } } /// /// public XmlReadMode ReadXml(Stream stream) { if (stream == null) return XmlReadMode.Auto; return ReadXml(new XmlTextReader(stream), false); } /// /// public XmlReadMode ReadXml(TextReader reader) { if (reader == null) return XmlReadMode.Auto; return ReadXml(new XmlTextReader(reader), false); } /// /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public XmlReadMode ReadXml(string fileName) { XmlTextReader xr = new XmlTextReader(fileName); try { return ReadXml(xr, false); } finally { xr.Close(); } } internal void InferSchema(XmlDocument xdoc, string[] excludedNamespaces, XmlReadMode mode) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, mode=%d{ds.XmlReadMode}\n", ObjectID, (int)mode); try { string ns = xdoc.DocumentElement.NamespaceURI; if (null == excludedNamespaces) { excludedNamespaces = new string[0]; } XmlNodeReader xnr = new XmlIgnoreNamespaceReader(xdoc, excludedNamespaces); System.Xml.Schema.XmlSchemaInference infer = new System.Xml.Schema.XmlSchemaInference(); infer.Occurrence = XmlSchemaInference.InferenceOption.Relaxed; if (mode == XmlReadMode.InferTypedSchema) infer.TypeInference = XmlSchemaInference.InferenceOption.Restricted; else infer.TypeInference = XmlSchemaInference.InferenceOption.Relaxed; XmlSchemaSet schemaSet = infer.InferSchema(xnr); schemaSet.Compile(); XSDSchema schema = new XSDSchema(); schema.FromInference = true; try { schema.LoadSchema(schemaSet, this); } finally { schema.FromInference = false; // this is always false if you are not calling fron inference } } finally { Bid.ScopeLeave(ref hscp); } } private bool IsEmpty() { foreach (DataTable table in this.Tables) if (table.Rows.Count > 0) return false; return true; } private void ReadXmlDiffgram(XmlReader reader) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { int d = reader.Depth; bool fEnforce = this.EnforceConstraints; this.EnforceConstraints = false; DataSet newDs; bool isEmpty = this.IsEmpty(); if (isEmpty) { newDs = this; } else { newDs = this.Clone(); newDs.EnforceConstraints = false; } foreach (DataTable t in newDs.Tables) { t.Rows.nullInList = 0; } reader.MoveToContent(); if ((reader.LocalName != Keywords.DIFFGRAM) && (reader.NamespaceURI != Keywords.DFFNS)) return; reader.Read(); if (reader.NodeType == XmlNodeType.Whitespace) MoveToElement(reader, reader.Depth - 1 /*iCurrentDepth*/); // skip over whitespaces. newDs.fInLoadDiffgram = true; if (reader.Depth > d) { if ((reader.NamespaceURI != Keywords.DFFNS) && (reader.NamespaceURI != Keywords.MSDNS)) { //we should be inside the dataset part XmlDocument xdoc = new XmlDocument(); XmlElement node = xdoc.CreateElement(reader.Prefix, reader.LocalName, reader.NamespaceURI); reader.Read(); if (reader.NodeType == XmlNodeType.Whitespace) { MoveToElement(reader, reader.Depth - 1 /*iCurrentDepth*/); // skip over whitespaces. } if (reader.Depth - 1 > d) { XmlDataLoader xmlload = new XmlDataLoader(newDs, false, node, false); xmlload.isDiffgram = true; // turn on the special processing xmlload.LoadData(reader); } ReadEndElement(reader); if (reader.NodeType == XmlNodeType.Whitespace) { MoveToElement(reader, reader.Depth - 1 /*iCurrentDepth*/); // skip over whitespaces. } } Debug.Assert(reader.NodeType != XmlNodeType.Whitespace, "Should not be on Whitespace node"); if (((reader.LocalName == Keywords.SQL_BEFORE) && (reader.NamespaceURI == Keywords.DFFNS)) || ((reader.LocalName == Keywords.MSD_ERRORS) && (reader.NamespaceURI == Keywords.DFFNS))) { //this will consume the changes and the errors part XMLDiffLoader diffLoader = new XMLDiffLoader(); diffLoader.LoadDiffGram(newDs, reader); } // get to the closing diff tag while (reader.Depth > d) { reader.Read(); } // read the closing tag ReadEndElement(reader); } foreach (DataTable t in newDs.Tables) { if (t.Rows.nullInList > 0) throw ExceptionBuilder.RowInsertMissing(t.TableName); } newDs.fInLoadDiffgram = false; //terrible performance! foreach (DataTable t in newDs.Tables) { DataRelation[] nestedParentRelations = t.NestedParentRelations; foreach (DataRelation rel in nestedParentRelations) { if (rel.ParentTable == t) { foreach (DataRow r in t.Rows) { foreach (DataRelation rel2 in nestedParentRelations) { r.CheckForLoops(rel2); } } } } } if (!isEmpty) { this.Merge(newDs); if (this.dataSetName == "NewDataSet") this.dataSetName = newDs.dataSetName; newDs.EnforceConstraints = fEnforce; } this.EnforceConstraints = fEnforce; } finally { Bid.ScopeLeave(ref hscp); } } /// /// public XmlReadMode ReadXml(XmlReader reader, XmlReadMode mode) { return ReadXml(reader, mode, false); } internal XmlReadMode ReadXml(XmlReader reader, XmlReadMode mode, bool denyResolving) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, mode=%d{ds.XmlReadMode}, denyResolving=%d{bool}\n", ObjectID, (int)mode, denyResolving); try { XmlReadMode ret = mode; if (reader == null) return ret; if (mode == XmlReadMode.Auto) { // Dev11 915079: nested ReadXml calls on the same DataSet must be done outside of RowDiffIdUsage scope return ReadXml(reader); } DataTable.DSRowDiffIdUsageSection rowDiffIdUsage = new DataTable.DSRowDiffIdUsageSection(); try { bool fSchemaFound = false; bool fDataFound = false; bool fIsXdr = false; int iCurrentDepth = -1; // Dev11 904428: prepare and cleanup rowDiffId hashtable rowDiffIdUsage.Prepare(this); if (reader is XmlTextReader) ((XmlTextReader)reader).WhitespaceHandling = WhitespaceHandling.Significant; XmlDocument xdoc = new XmlDocument(); // we may need this to infer the schema if ((mode != XmlReadMode.Fragment) && (reader.NodeType == XmlNodeType.Element)) iCurrentDepth = reader.Depth; reader.MoveToContent(); XmlDataLoader xmlload = null; if (reader.NodeType == XmlNodeType.Element) { XmlElement topNode = null; if (mode == XmlReadMode.Fragment) { xdoc.AppendChild(xdoc.CreateElement("ds_sqlXmlWraPPeR")); topNode = xdoc.DocumentElement; } else { //handle the top node if ((reader.LocalName == Keywords.DIFFGRAM) && (reader.NamespaceURI == Keywords.DFFNS)) { if ((mode == XmlReadMode.DiffGram) || (mode == XmlReadMode.IgnoreSchema)) { this.ReadXmlDiffgram(reader); // read the closing tag of the current element ReadEndElement(reader); } else { reader.Skip(); } return ret; } if (reader.LocalName == Keywords.XDR_SCHEMA && reader.NamespaceURI == Keywords.XDRNS) { // load XDR schema and exit if ((mode != XmlReadMode.IgnoreSchema) && (mode != XmlReadMode.InferSchema) && (mode != XmlReadMode.InferTypedSchema)) { ReadXDRSchema(reader); } else { reader.Skip(); } return ret; //since the top level element is a schema return } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI == Keywords.XSDNS) { // load XSD schema and exit if ((mode != XmlReadMode.IgnoreSchema) && (mode != XmlReadMode.InferSchema) && (mode != XmlReadMode.InferTypedSchema)) { ReadXSDSchema(reader, denyResolving); } else reader.Skip(); return ret; //since the top level element is a schema return } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI.StartsWith(Keywords.XSD_NS_START, StringComparison.Ordinal)) throw ExceptionBuilder.DataSetUnsupportedSchema(Keywords.XSDNS); // now either the top level node is a table and we load it through dataReader... // ... or backup the top node and all its attributes topNode = xdoc.CreateElement(reader.Prefix, reader.LocalName, reader.NamespaceURI); if (reader.HasAttributes) { int attrCount = reader.AttributeCount; for (int i = 0; i < attrCount; i++) { reader.MoveToAttribute(i); if (reader.NamespaceURI.Equals(Keywords.XSD_XMLNS_NS)) topNode.SetAttribute(reader.Name, reader.GetAttribute(i)); else { XmlAttribute attr = topNode.SetAttributeNode(reader.LocalName, reader.NamespaceURI); attr.Prefix = reader.Prefix; attr.Value = reader.GetAttribute(i); } } } reader.Read(); } while (MoveToElement(reader, iCurrentDepth)) { if (reader.LocalName == Keywords.XDR_SCHEMA && reader.NamespaceURI == Keywords.XDRNS) { // load XDR schema if (!fSchemaFound && !fDataFound && (mode != XmlReadMode.IgnoreSchema) && (mode != XmlReadMode.InferSchema) && (mode != XmlReadMode.InferTypedSchema)) { ReadXDRSchema(reader); fSchemaFound = true; fIsXdr = true; } else { reader.Skip(); } continue; } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI == Keywords.XSDNS) { // load XSD schema and exit if ((mode != XmlReadMode.IgnoreSchema) && (mode != XmlReadMode.InferSchema) && (mode != XmlReadMode.InferTypedSchema)) { ReadXSDSchema(reader, denyResolving); fSchemaFound = true; } else { reader.Skip(); } continue; } if ((reader.LocalName == Keywords.DIFFGRAM) && (reader.NamespaceURI == Keywords.DFFNS)) { if ((mode == XmlReadMode.DiffGram) || (mode == XmlReadMode.IgnoreSchema)) { this.ReadXmlDiffgram(reader); ret = XmlReadMode.DiffGram; } else { reader.Skip(); } continue; } if (reader.LocalName == Keywords.XSD_SCHEMA && reader.NamespaceURI.StartsWith(Keywords.XSD_NS_START, StringComparison.Ordinal)) throw ExceptionBuilder.DataSetUnsupportedSchema(Keywords.XSDNS); if (mode == XmlReadMode.DiffGram) { reader.Skip(); continue; // we do not read data in diffgram mode } // if we are here we found some data fDataFound = true; if (mode == XmlReadMode.InferSchema || mode == XmlReadMode.InferTypedSchema) { //save the node in DOM until the end; XmlNode node = xdoc.ReadNode(reader); topNode.AppendChild(node); } else { if (xmlload == null) xmlload = new XmlDataLoader(this, fIsXdr, topNode, mode == XmlReadMode.IgnoreSchema); xmlload.LoadData(reader); } } //end of the while // read the closing tag of the current element ReadEndElement(reader); // now top node contains the data part xdoc.AppendChild(topNode); if (xmlload == null) xmlload = new XmlDataLoader(this, fIsXdr, mode == XmlReadMode.IgnoreSchema); if (mode == XmlReadMode.DiffGram) { // we already got the diffs through XmlReader interface return ret; } // Load Data if (mode == XmlReadMode.InferSchema || mode == XmlReadMode.InferTypedSchema) { InferSchema(xdoc, null, mode); ret = XmlReadMode.InferSchema; xmlload.FromInference = true; // } try { xmlload.LoadData(xdoc); } finally { xmlload.FromInference = false; } } } return ret; } finally { // Dev11 904428: prepare and cleanup rowDiffId hashtable rowDiffIdUsage.Cleanup(); } } finally { Bid.ScopeLeave(ref hscp); } } /// /// public XmlReadMode ReadXml(Stream stream, XmlReadMode mode) { if (stream == null) return XmlReadMode.Auto; XmlTextReader reader = (mode == XmlReadMode.Fragment) ? new XmlTextReader(stream, XmlNodeType.Element, null) : new XmlTextReader(stream); return ReadXml(reader, mode, false); } /// /// public XmlReadMode ReadXml(TextReader reader, XmlReadMode mode) { if (reader == null) return XmlReadMode.Auto; XmlTextReader xmlreader = (mode == XmlReadMode.Fragment) ? new XmlTextReader(reader.ReadToEnd(), XmlNodeType.Element, null) : new XmlTextReader(reader); return ReadXml(xmlreader, mode, false); } /// /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public XmlReadMode ReadXml(string fileName, XmlReadMode mode) { XmlTextReader xr = null; if (mode == XmlReadMode.Fragment) { FileStream stream = new FileStream(fileName, FileMode.Open); xr = new XmlTextReader(stream, XmlNodeType.Element, null); } else xr = new XmlTextReader(fileName); try { return ReadXml(xr, mode, false); } finally { xr.Close(); } } /// /// Writes schema and data for the DataSet. /// public void WriteXml(Stream stream) { WriteXml(stream, XmlWriteMode.IgnoreSchema); } /// /// public void WriteXml(TextWriter writer) { WriteXml(writer, XmlWriteMode.IgnoreSchema); } /// /// public void WriteXml(XmlWriter writer) { WriteXml(writer, XmlWriteMode.IgnoreSchema); } /// /// [To be supplied.] /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void WriteXml(String fileName) { WriteXml(fileName, XmlWriteMode.IgnoreSchema); } /// /// Writes schema and data for the DataSet. /// public void WriteXml(Stream stream, XmlWriteMode mode) { if (stream != null) { XmlTextWriter w = new XmlTextWriter(stream, null); w.Formatting = Formatting.Indented; WriteXml(w, mode); } } /// /// public void WriteXml(TextWriter writer, XmlWriteMode mode) { if (writer != null) { XmlTextWriter w = new XmlTextWriter(writer); w.Formatting = Formatting.Indented; WriteXml(w, mode); } } /// /// public void WriteXml(XmlWriter writer, XmlWriteMode mode) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, mode=%d{ds.XmlWriteMode}\n", ObjectID, (int)mode); try { // Generate SchemaTree and write it out if (writer != null) { if (mode == XmlWriteMode.DiffGram) { // Create and save the updates // new UpdateTreeGen(UpdateTreeGen.UPDATE, (DataRowState)(-1), this).Save(writer, null); new NewDiffgramGen(this).Save(writer); } else { // Create and save xml data new XmlDataTreeWriter(this).Save(writer, mode == XmlWriteMode.WriteSchema); } } } finally { Bid.ScopeLeave(ref hscp); } } /// /// [To be supplied.] /// [ResourceExposure(ResourceScope.Machine)] [ResourceConsumption(ResourceScope.Machine)] public void WriteXml(String fileName, XmlWriteMode mode) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, fileName='%ls', mode=%d{ds.XmlWriteMode}\n", ObjectID, fileName, (int)mode); XmlTextWriter xw = new XmlTextWriter(fileName, null); try { xw.Formatting = Formatting.Indented; xw.WriteStartDocument(true); if (xw != null) { // Create and save the updates if (mode == XmlWriteMode.DiffGram) { new NewDiffgramGen(this).Save(xw); } else { // Create and save xml data new XmlDataTreeWriter(this).Save(xw, mode == XmlWriteMode.WriteSchema); } } xw.WriteEndDocument(); } finally { xw.Close(); Bid.ScopeLeave(ref hscp); } } /// /// /// Gets the collection of parent relations which belong to a /// specified table. /// /// internal DataRelationCollection GetParentRelations(DataTable table) { return table.ParentRelations; } /// /// /// Merges this into a specified . /// /// public void Merge(DataSet dataSet) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, dataSet=%d\n", ObjectID, (dataSet != null) ? dataSet.ObjectID : 0); try { Merge(dataSet, false, MissingSchemaAction.Add); } finally { Bid.ScopeLeave(ref hscp); } } /// /// /// Merges this into a specified preserving changes according to /// the specified argument. /// /// public void Merge(DataSet dataSet, bool preserveChanges) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, dataSet=%d, preserveChanges=%d{bool}\n", ObjectID, (dataSet != null) ? dataSet.ObjectID : 0, preserveChanges); try { Merge(dataSet, preserveChanges, MissingSchemaAction.Add); } finally { Bid.ScopeLeave(ref hscp); } } /// /// /// Merges this into a specified preserving changes according to /// the specified argument, and handling an incompatible schema according to the /// specified argument. /// /// public void Merge(DataSet dataSet, bool preserveChanges, MissingSchemaAction missingSchemaAction) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, dataSet=%d, preserveChanges=%d{bool}, missingSchemaAction=%d{ds.MissingSchemaAction}\n", ObjectID, (dataSet != null) ? dataSet.ObjectID : 0, preserveChanges, (int)missingSchemaAction); try { // Argument checks if (dataSet == null) throw ExceptionBuilder.ArgumentNull("dataSet"); switch (missingSchemaAction) { // @perfnote: Enum.IsDefined case MissingSchemaAction.Add: case MissingSchemaAction.Ignore: case MissingSchemaAction.Error: case MissingSchemaAction.AddWithKey: Merger merger = new Merger(this, preserveChanges, missingSchemaAction); merger.MergeDataSet(dataSet); break; default: throw Common.ADP.InvalidMissingSchemaAction(missingSchemaAction); } } finally { Bid.ScopeLeave(ref hscp); } } /// /// /// Merges this into a specified . /// /// public void Merge(DataTable table) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, table=%d\n", ObjectID, (table != null) ? table.ObjectID : 0); try { Merge(table, false, MissingSchemaAction.Add); } finally { Bid.ScopeLeave(ref hscp); } } /// /// /// Merges this into a specified . with a value to preserve changes /// made to the target, and a value to deal with missing schemas. /// /// public void Merge(DataTable table, bool preserveChanges, MissingSchemaAction missingSchemaAction) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, table=%d, preserveChanges=%d{bool}, missingSchemaAction=%d{ds.MissingSchemaAction}\n", ObjectID, (table != null) ? table.ObjectID : 0, preserveChanges, (int)missingSchemaAction); try { // Argument checks if (table == null) throw ExceptionBuilder.ArgumentNull("table"); switch (missingSchemaAction) { // @perfnote: Enum.IsDefined case MissingSchemaAction.Add: case MissingSchemaAction.Ignore: case MissingSchemaAction.Error: case MissingSchemaAction.AddWithKey: Merger merger = new Merger(this, preserveChanges, missingSchemaAction); merger.MergeTable(table); break; default: throw Common.ADP.InvalidMissingSchemaAction(missingSchemaAction); } } finally { Bid.ScopeLeave(ref hscp); } } /// /// [To be supplied.] /// public void Merge(DataRow[] rows) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, rows\n", ObjectID); try { Merge(rows, false, MissingSchemaAction.Add); } finally { Bid.ScopeLeave(ref hscp); } } /// /// [To be supplied.] /// public void Merge(DataRow[] rows, bool preserveChanges, MissingSchemaAction missingSchemaAction) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#, preserveChanges=%d{bool}, missingSchemaAction=%d{ds.MissingSchemaAction}\n", ObjectID, preserveChanges, (int)missingSchemaAction); try { // Argument checks if (rows == null) throw ExceptionBuilder.ArgumentNull("rows"); switch (missingSchemaAction) { // @perfnote: Enum.IsDefined case MissingSchemaAction.Add: case MissingSchemaAction.Ignore: case MissingSchemaAction.Error: case MissingSchemaAction.AddWithKey: Merger merger = new Merger(this, preserveChanges, missingSchemaAction); merger.MergeRows(rows); break; default: throw Common.ADP.InvalidMissingSchemaAction(missingSchemaAction); } } finally { Bid.ScopeLeave(ref hscp); } } protected virtual void OnPropertyChanging(PropertyChangedEventArgs pcevent) { if (onPropertyChangingDelegate != null) onPropertyChangingDelegate(this, pcevent); } /// /// Inheriting classes should override this method to handle this event. /// Call base.OnMergeFailed to send this event to any registered event /// listeners. /// internal void OnMergeFailed(MergeFailedEventArgs mfevent) { if (onMergeFailed != null) onMergeFailed(this, mfevent); else throw ExceptionBuilder.MergeFailed(mfevent.Conflict); } internal void RaiseMergeFailed(DataTable table, string conflict, MissingSchemaAction missingSchemaAction) { if (MissingSchemaAction.Error == missingSchemaAction) throw ExceptionBuilder.MergeFailed(conflict); MergeFailedEventArgs mfevent = new MergeFailedEventArgs(table, conflict); OnMergeFailed(mfevent); return; } internal void OnDataRowCreated(DataRow row) { if (onDataRowCreated != null) onDataRowCreated(this, row); } internal void OnClearFunctionCalled(DataTable table) { if (onClearFunctionCalled != null) onClearFunctionCalled(this, table); } private void OnInitialized() { if (onInitialized != null) { onInitialized(this, EventArgs.Empty); } } /// /// This method should be overriden by subclasses to restrict tables being removed. /// protected internal virtual void OnRemoveTable(DataTable table) { } internal void OnRemovedTable(DataTable table) { DataViewManager viewManager = defaultViewManager; if (null != viewManager) { viewManager.DataViewSettings.Remove(table); } } /// /// This method should be overriden by subclasses to restrict tables being removed. /// protected virtual void OnRemoveRelation(DataRelation relation) { } // internal void OnRemoveRelationHack(DataRelation relation) { OnRemoveRelation(relation); } protected internal void RaisePropertyChanging(string name) { OnPropertyChanging(new PropertyChangedEventArgs(name)); } internal DataTable[] TopLevelTables() { return TopLevelTables(false); } internal DataTable[] TopLevelTables(bool forSchema) { // first let's figure out if we can represent the given dataSet as a tree using // the fact that all connected undirected graphs with n-1 edges are trees. List topTables = new List(); if (forSchema) { // prepend the tables that are nested more than once for (int i = 0; i < Tables.Count; i++) { DataTable table = Tables[i]; if (table.NestedParentsCount > 1 || table.SelfNested) topTables.Add(table); } } for (int i = 0; i < Tables.Count; i++) { DataTable table = Tables[i]; if (table.NestedParentsCount == 0 && !topTables.Contains(table)) topTables.Add(table); } if (topTables.Count == 0) return zeroTables; return topTables.ToArray(); } /// /// This method rolls back all the changes to have been made to this DataSet since /// it was loaded or the last time AcceptChanges was called. /// Any rows still in edit-mode cancel their edits. New rows get removed. Modified and /// Deleted rows return back to their original state. /// public virtual void RejectChanges() { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { bool fEnforce = EnforceConstraints; EnforceConstraints = false; for (int i = 0; i < Tables.Count; i++) Tables[i].RejectChanges(); EnforceConstraints = fEnforce; } finally { Bid.ScopeLeave(ref hscp); } } /// /// Resets the dataSet back to it's original state. Subclasses should override /// to restore back to it's original state. /// public virtual void Reset() { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { for (int i = 0; i < Tables.Count; i++) { ConstraintCollection cons = Tables[i].Constraints; for (int j = 0; j < cons.Count; ) { if (cons[j] is ForeignKeyConstraint) { cons.Remove(cons[j]); } else j++; } } // SQLBU 502734: because of SQLBU 501916, dependent tables need to be notified when a table is cleared // if relations are removed first, then exceptions happen Clear(); Relations.Clear(); Tables.Clear(); } finally { Bid.ScopeLeave(ref hscp); } } internal bool ValidateCaseConstraint() { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { DataRelation relation = null; for (int i = 0; i < Relations.Count; i++) { relation = Relations[i]; if (relation.ChildTable.CaseSensitive != relation.ParentTable.CaseSensitive) return false; } ForeignKeyConstraint constraint = null; ConstraintCollection constraints = null; for (int i = 0; i < Tables.Count; i++) { constraints = Tables[i].Constraints; for (int j = 0; j < constraints.Count; j++) { if (constraints[j] is ForeignKeyConstraint) { constraint = (ForeignKeyConstraint)constraints[j]; if (constraint.Table.CaseSensitive != constraint.RelatedTable.CaseSensitive) return false; } } } return true; } finally { Bid.ScopeLeave(ref hscp); } } internal bool ValidateLocaleConstraint() { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { DataRelation relation = null; for (int i = 0; i < Relations.Count; i++) { relation = Relations[i]; if (relation.ChildTable.Locale.LCID != relation.ParentTable.Locale.LCID) return false; } ForeignKeyConstraint constraint = null; ConstraintCollection constraints = null; for (int i = 0; i < Tables.Count; i++) { constraints = Tables[i].Constraints; for (int j = 0; j < constraints.Count; j++) { if (constraints[j] is ForeignKeyConstraint) { constraint = (ForeignKeyConstraint)constraints[j]; if (constraint.Table.Locale.LCID != constraint.RelatedTable.Locale.LCID) return false; } } } return true; } finally { Bid.ScopeLeave(ref hscp); } } // [....]: may be better to rewrite this as nonrecursive? internal DataTable FindTable(DataTable baseTable, PropertyDescriptor[] props, int propStart) { if (props.Length < propStart + 1) return baseTable; PropertyDescriptor currentProp = props[propStart]; if (baseTable == null) { // the accessor is the table name. if we don't find it, return null. if (currentProp is DataTablePropertyDescriptor) { return FindTable(((DataTablePropertyDescriptor)currentProp).Table, props, propStart + 1); } return null; } if (currentProp is DataRelationPropertyDescriptor) { return FindTable(((DataRelationPropertyDescriptor)currentProp).Relation.ChildTable, props, propStart + 1); } return null; } protected virtual void ReadXmlSerializable(XmlReader reader) { //WebData 96421 and 104709, this is DataSet side fix for the thrown exception // does not mean DataSet is null,but it does not have any child // so dont do anything, ignore the attributes and just return empty DataSet; this.UseDataSetSchemaOnly = false; this.UdtIsWrapped = false; if (reader.HasAttributes) { const string xsinill = Keywords.XSI + ":" + Keywords.XSI_NIL; if (reader.MoveToAttribute(xsinill)) { string nilAttrib = reader.GetAttribute(xsinill); if (string.Compare(nilAttrib, "true", StringComparison.Ordinal) == 0) {// case sensitive true comparison MoveToElement(reader, 1); return; } } const string useDataSetSchemaOnlyString = Keywords.MSD + ":" + Keywords.USEDATASETSCHEMAONLY; if (reader.MoveToAttribute(useDataSetSchemaOnlyString)) { string _useDataSetSchemaOnly = reader.GetAttribute(useDataSetSchemaOnlyString); if (string.Equals(_useDataSetSchemaOnly, "true", StringComparison.Ordinal) || string.Equals(_useDataSetSchemaOnly, "1", StringComparison.Ordinal)) { this.UseDataSetSchemaOnly = true; } else if (!string.Equals(_useDataSetSchemaOnly, "false", StringComparison.Ordinal) && !string.Equals(_useDataSetSchemaOnly, "0", StringComparison.Ordinal)) { throw ExceptionBuilder.InvalidAttributeValue(Keywords.USEDATASETSCHEMAONLY, _useDataSetSchemaOnly); } } const string udtIsWrappedString = Keywords.MSD + ":" + Keywords.UDTCOLUMNVALUEWRAPPED; if (reader.MoveToAttribute(udtIsWrappedString)) { string _udtIsWrappedString = reader.GetAttribute(udtIsWrappedString); if (string.Equals(_udtIsWrappedString, "true", StringComparison.Ordinal) || string.Equals(_udtIsWrappedString, "1", StringComparison.Ordinal)) { this.UdtIsWrapped = true; } else if (!string.Equals(_udtIsWrappedString, "false", StringComparison.Ordinal) && !string.Equals(_udtIsWrappedString, "0", StringComparison.Ordinal)) { throw ExceptionBuilder.InvalidAttributeValue(Keywords.UDTCOLUMNVALUEWRAPPED, _udtIsWrappedString); } } } ReadXml(reader, XmlReadMode.DiffGram, true); } protected virtual System.Xml.Schema.XmlSchema GetSchemaSerializable() { return null; } /************************************************************************ To publish int_tools\webserviceadmin.exe -install Application Application.dll To test http://localhost/application/service.asmx?wsdl or wsdl.exe /namespace:UserNamespace http://localhost/Application/Service.asmx?wsdl /out:Service.cs The V1.0 & V1.1 WSDL for Untyped DataSet being returned as a result (no parameters) The V1.0 & V1.1 WSDL for Untyped DataSet as parameter, string for the result The V2.0 WSDL for Untyped DataSet being returned as a result (no parameters) The V2.0 WSDL for Untyped DataSet as a parameter, string for the result The V1.0, V1.1 & V2.0 WSDL for Typed DataSet ************************************************************************/ public static XmlSchemaComplexType GetDataSetSchema(XmlSchemaSet schemaSet) { // For performance resons we are exploiting the fact that config files content is constant // for a given appdomain so we can safely cache the prepared schema complex type and reuse it if (schemaTypeForWSDL == null) { // to change the config file, appdomain needs to restart; so it seems safe to cache the schema XmlSchemaComplexType tempWSDL = new XmlSchemaComplexType(); XmlSchemaSequence sequence = new XmlSchemaSequence(); if (PublishLegacyWSDL()) { // Default is Version 1.0 XmlSchemaElement elem = new XmlSchemaElement(); elem.RefName = new XmlQualifiedName(Keywords.XSD_SCHEMA, Keywords.XSDNS); sequence.Items.Add(elem); XmlSchemaAny any = new XmlSchemaAny(); sequence.Items.Add(any); } else { // this means Version == V2.0 or newer XmlSchemaAny any = new XmlSchemaAny(); any.Namespace = XmlSchema.Namespace; any.MinOccurs = 0; any.ProcessContents = XmlSchemaContentProcessing.Lax; sequence.Items.Add(any); any = new XmlSchemaAny(); any.Namespace = Keywords.DFFNS; any.MinOccurs = 0; // when recognizing WSDL - MinOccurs="0" denotes DataSet, a MinOccurs="1" for DataTable any.ProcessContents = XmlSchemaContentProcessing.Lax; sequence.Items.Add(any); sequence.MaxOccurs = Decimal.MaxValue; } tempWSDL.Particle = sequence; schemaTypeForWSDL = tempWSDL; } return schemaTypeForWSDL; } /********************************************
*******************************************/ private static bool PublishLegacyWSDL() { Single version = 1.0f; // Default is Version 1.0 #if !NO_CONFIGURATION NameValueCollection settings = (NameValueCollection)PrivilegedConfigurationManager.GetSection(Keywords.WS_DATASETFULLQNAME); if (settings != null) { string[] values = settings.GetValues(Keywords.WS_VERSION); if ((null != values) && (0 < values.Length) && (null != values[0])) { // will throw FormatException if not a valid number version = Single.Parse(values[0], CultureInfo.InvariantCulture); } } #endif return (version < 2.0f); // if config does not exist, Default is Version 1.0 } XmlSchema IXmlSerializable.GetSchema() { if (GetType() == typeof(DataSet)) { return null; } MemoryStream stream = new MemoryStream(); // WriteXmlSchema(new XmlTextWriter(stream, null)); XmlWriter writer = new XmlTextWriter(stream, null); if (writer != null) { (new XmlTreeGen(SchemaFormat.WebService)).Save(this, writer); } stream.Position = 0; return XmlSchema.Read(new XmlTextReader(stream), null); // return GetSchemaSerializable(); } void IXmlSerializable.ReadXml(XmlReader reader) { bool fNormalization = true; XmlTextReader xmlTextReader = null; IXmlTextParser xmlTextParser = reader as IXmlTextParser; if (xmlTextParser != null) { fNormalization = xmlTextParser.Normalized; xmlTextParser.Normalized = false; } else { xmlTextReader = reader as XmlTextReader; if (xmlTextReader != null) { fNormalization = xmlTextReader.Normalization; xmlTextReader.Normalization = false; } } ReadXmlSerializable(reader); if (xmlTextParser != null) xmlTextParser.Normalized = fNormalization; else if (xmlTextReader != null) xmlTextReader.Normalization = fNormalization; } void IXmlSerializable.WriteXml(XmlWriter writer) { this.WriteXmlSchema(writer, SchemaFormat.WebService, (Converter)null); this.WriteXml(writer, XmlWriteMode.DiffGram); } public virtual void Load(IDataReader reader, LoadOption loadOption, FillErrorEventHandler errorHandler, params DataTable[] tables) { IntPtr hscp; Bid.ScopeEnter(out hscp, " reader, loadOption=%d{ds.LoadOption}", (int)loadOption); try { foreach (DataTable dt in tables) { Common.ADP.CheckArgumentNull(dt, "tables"); if (dt.DataSet != this) { throw ExceptionBuilder.TableNotInTheDataSet(dt.TableName); } } Common.LoadAdapter adapter = new Common.LoadAdapter(); adapter.FillLoadOption = loadOption; adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey; if (null != errorHandler) { adapter.FillError += errorHandler; } adapter.FillFromReader(tables, reader, 0, 0); if (!reader.IsClosed && !reader.NextResult()) { // reader.Close(); } } finally { Bid.ScopeLeave(ref hscp); } } public void Load(IDataReader reader, LoadOption loadOption, params DataTable[] tables) { Load(reader, loadOption, null, tables); } public void Load(IDataReader reader, LoadOption loadOption, params string[] tables) { Common.ADP.CheckArgumentNull(tables, "tables"); DataTable[] dataTables = new DataTable[tables.Length]; for (int i = 0; i < tables.Length; i++) { DataTable tempDT = this.Tables[tables[i]]; if (null == tempDT) { tempDT = new DataTable(tables[i]); // fxcop: new DataTable should inherit the CaseSensitive, Locale, Namespace from DataSet Tables.Add(tempDT); } dataTables[i] = tempDT; } Load(reader, loadOption, null, dataTables); } public DataTableReader CreateDataReader() { if (Tables.Count == 0) throw ExceptionBuilder.CannotCreateDataReaderOnEmptyDataSet(); DataTable[] dataTables = new DataTable[Tables.Count]; for (int i = 0; i < Tables.Count; i++) { dataTables[i] = Tables[i]; } return CreateDataReader(dataTables); } public DataTableReader CreateDataReader(params DataTable[] dataTables) { IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); try { if (dataTables.Length == 0) throw ExceptionBuilder.DataTableReaderArgumentIsEmpty(); for (int i = 0; i < dataTables.Length; i++) { if (dataTables[i] == null) throw ExceptionBuilder.ArgumentContainsNullValue(); } return new DataTableReader(dataTables); } finally { Bid.ScopeLeave(ref hscp); } } internal string MainTableName { get { return mainTableName; } set { this.mainTableName = value; } } internal int ObjectID { get { return _objectID; } } } #if !NO_CODEDOM public class DataSetSchemaImporterExtension : SchemaImporterExtension { // DataSetSchemaImporterExtension is used for WebServices, it is used to recognize the schema of DataSet within wsdl // If a non 2.0 enabled DataSetSchemaImporterExtension, wsdl will generate a classes that you can't cast to dataset / datatable Hashtable importedTypes = new Hashtable(); /// /// [To be supplied.] /// public override string ImportSchemaType(string name, string schemaNamespace, XmlSchemaObject context, XmlSchemas schemas, XmlSchemaImporter importer, CodeCompileUnit compileUnit, CodeNamespace mainNamespace, CodeGenerationOptions options, CodeDomProvider codeProvider) { IList values = schemas.GetSchemas(schemaNamespace); if (values.Count != 1) { return null; } XmlSchema schema = values[0] as XmlSchema; if (schema == null) return null; XmlSchemaType type = (XmlSchemaType)schema.SchemaTypes[new XmlQualifiedName(name, schemaNamespace)]; return ImportSchemaType(type, context, schemas, importer, compileUnit, mainNamespace, options, codeProvider); } /// /// [To be supplied.] /// public override string ImportSchemaType(XmlSchemaType type, XmlSchemaObject context, XmlSchemas schemas, XmlSchemaImporter importer, CodeCompileUnit compileUnit, CodeNamespace mainNamespace, CodeGenerationOptions options, CodeDomProvider codeProvider) { if (type == null) { return null; } if (importedTypes[type] != null) { mainNamespace.Imports.Add(new CodeNamespaceImport(typeof(DataSet).Namespace)); compileUnit.ReferencedAssemblies.Add("System.Data.dll"); return (string)importedTypes[type]; } if (!(context is XmlSchemaElement)) return null; XmlSchemaElement e = (XmlSchemaElement)context; // recognizing the following is important, but not as part of SQLPT 120015394: Support WSI Compliant WSDL for DataSet // // see also SQLBU 338644, 410965, 423446 //if (IsDataSet(e)) //{ // return GenerateTypedDataSet(e, schemas, mainNamespace, compileUnit.ReferencedAssemblies, codeProvider); //} if (type is XmlSchemaComplexType) { XmlSchemaComplexType ct = (XmlSchemaComplexType)type; if (ct.Particle is XmlSchemaSequence) { XmlSchemaObjectCollection items = ((XmlSchemaSequence)ct.Particle).Items; if ((2 == items.Count) && (items[0] is XmlSchemaAny) && (items[1] is XmlSchemaAny)) { XmlSchemaAny any0 = (XmlSchemaAny)items[0]; XmlSchemaAny any1 = (XmlSchemaAny)items[1]; if ((any0.Namespace == XmlSchema.Namespace) && (any1.Namespace == "urn:schemas-microsoft-com:xml-diffgram-v1")) { // new diffgramm format string ns = null; foreach (XmlSchemaAttribute a in ct.Attributes) { if (a.Name == "namespace") { ns = a.FixedValue.Trim(); break; } } bool isDataSet = false; // check for DataSet or DataTable if (((XmlSchemaSequence)ct.Particle).MaxOccurs == Decimal.MaxValue) { isDataSet = true; } else if (any0.MaxOccurs == Decimal.MaxValue) { isDataSet = false; } else { return null; } if (ns == null) { //Un-Typed DataSet / DataTable string typeName = isDataSet ? typeof(DataSet).FullName : typeof(DataTable).FullName; importedTypes.Add(type, typeName); mainNamespace.Imports.Add(new CodeNamespaceImport(typeof(DataSet).Namespace)); compileUnit.ReferencedAssemblies.Add("System.Data.dll"); return typeName; } else { // Typed DataSet / DataTable foreach (XmlSchema schema in schemas.GetSchemas(ns)) { if ((schema != null) && (schema.Id != null)) { XmlSchemaElement ds = FindDataSetElement(schema); // implement FindDataTableElement(schema) if (ds != null) { return ImportSchemaType(ds.SchemaType, ds, schemas, importer, compileUnit, mainNamespace, options, codeProvider); } // else return null } } return null; } } } } if (ct.Particle is XmlSchemaSequence || ct.Particle is XmlSchemaAll) { XmlSchemaObjectCollection items = ((XmlSchemaGroupBase)ct.Particle).Items; if (items.Count == 2) { if (!(items[0] is XmlSchemaElement && items[1] is XmlSchemaAny)) return null; XmlSchemaElement schema = (XmlSchemaElement)items[0]; if (!(schema.RefName.Name == "schema" && schema.RefName.Namespace == XmlSchema.Namespace)) return null; string typeName = typeof(DataSet).FullName; importedTypes.Add(type, typeName); mainNamespace.Imports.Add(new CodeNamespaceImport(typeof(DataSet).Namespace)); compileUnit.ReferencedAssemblies.Add("System.Data.dll"); return typeName; } else if (1 == items.Count) { XmlSchemaAny any = items[0] as XmlSchemaAny; if ((null != any) && (null != any.Namespace) && (any.Namespace.IndexOfAny(new char[] { '#', ' ' }) < 0)) // special syntax (##any, ##other, ...) or more than one Uri present { foreach (XmlSchema schema in schemas.GetSchemas(any.Namespace)) { if ((null != schema) && (null != schema.Id)) { XmlSchemaElement ds = FindDataSetElement(schema); if (ds != null) { return ImportSchemaType(ds.SchemaType, ds, schemas, importer, compileUnit, mainNamespace, options, codeProvider); } // else return null } // else return null } } // else return null } } } return null; } internal XmlSchemaElement FindDataSetElement(XmlSchema schema) { foreach (XmlSchemaObject item in schema.Items) { if (item is XmlSchemaElement && IsDataSet((XmlSchemaElement)item)) { return (XmlSchemaElement)item; } } return null; } internal string GenerateTypedDataSet(XmlSchemaElement element, XmlSchemas schemas, CodeNamespace codeNamespace, StringCollection references, CodeDomProvider codeProvider) { if (element == null) return null; if (importedTypes[element.SchemaType] != null) return (string)importedTypes[element.SchemaType]; IList values = schemas.GetSchemas(element.QualifiedName.Namespace); if (values.Count != 1) { return null; } XmlSchema schema = values[0] as XmlSchema; if (schema == null) return null; DataSet ds = new DataSet(); // using (MemoryStream stream = new MemoryStream()) { schema.Write(stream); stream.Position = 0; ds.ReadXmlSchema(stream); } #pragma warning disable 618 // ignore obsolete warning about TypedDataSetGenerator CodeTypeDeclaration dsClass = new TypedDataSetGenerator().GenerateCode(ds, codeNamespace, codeProvider.CreateGenerator()); #pragma warning restore 618 string typeName = dsClass.Name; importedTypes.Add(element.SchemaType, typeName); references.Add("System.Data.dll"); return typeName; } internal static bool IsDataSet(XmlSchemaElement e) { if (e.UnhandledAttributes != null) { foreach (XmlAttribute a in e.UnhandledAttributes) { if (a.LocalName == "IsDataSet" && a.NamespaceURI == Keywords.MSDNS) { // currently the msdata:IsDataSet uses its own format for the boolean values if (a.Value == "True" || a.Value == "true" || a.Value == "1") return true; } } } return false; } } #endif }