Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DLinq / Dlinq / Mapping / MappingSource.cs / 1 / MappingSource.cs
using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq.Expressions; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Xml; using System.Xml.Serialization; using LinqToSqlShared.Mapping; namespace System.Data.Linq.Mapping { using System.Data.Linq.Provider; using System.Diagnostics.CodeAnalysis; ////// Represents a source for mapping information. /// public abstract class MappingSource { MetaModel primaryModel; ReaderWriterLock rwlock; DictionarysecondaryModels; /// /// Gets the MetaModel representing a DataContext and all it's /// accessible tables, functions and entities. /// public MetaModel GetModel(Type dataContextType) { if (dataContextType == null) { throw Error.ArgumentNull("dataContextType"); } MetaModel model = null; if (this.primaryModel == null) { model = this.CreateModel(dataContextType); Interlocked.CompareExchange(ref this.primaryModel, model, null); } // if the primary one matches, use it! if (this.primaryModel.ContextType == dataContextType) { return this.primaryModel; } // the rest of this only happens if you are using the mapping source for // more than one context type // build a map if one is not already defined if (this.secondaryModels == null) { Interlocked.CompareExchange >(ref this.secondaryModels, new Dictionary (), null); } // if we haven't created a read/writer lock, make one now if (this.rwlock == null) { Interlocked.CompareExchange (ref this.rwlock, new ReaderWriterLock(), null); } // lock the map and look inside MetaModel foundModel; this.rwlock.AcquireReaderLock(Timeout.Infinite); try { if (this.secondaryModels.TryGetValue(dataContextType, out foundModel)) { return foundModel; } } finally { this.rwlock.ReleaseReaderLock(); } // if it wasn't found, lock for write and try again this.rwlock.AcquireWriterLock(Timeout.Infinite); try { if (this.secondaryModels.TryGetValue(dataContextType, out foundModel)) { return foundModel; } if (model == null) { model = this.CreateModel(dataContextType); } this.secondaryModels.Add(dataContextType, model); } finally { this.rwlock.ReleaseWriterLock(); } return model; } /// /// Creates a new instance of a MetaModel. This method is called by GetModel(). /// Override this method when defining a new type of MappingSource. /// /// ///protected abstract MetaModel CreateModel(Type dataContextType); } /// /// A mapping source that uses attributes on the context to create the mapping model. /// public sealed class AttributeMappingSource : MappingSource { public AttributeMappingSource() { } protected override MetaModel CreateModel(Type dataContextType) { if (dataContextType == null) { throw Error.ArgumentNull("dataContextType"); } return new AttributedMetaModel(this, dataContextType); } } ////// A mapping source that uses an external XML mapping source to create the model. /// public sealed class XmlMappingSource : MappingSource { DatabaseMapping map; private XmlMappingSource(DatabaseMapping map) { this.map = map; } protected override MetaModel CreateModel(Type dataContextType) { if (dataContextType == null) { throw Error.ArgumentNull("dataContextType"); } return new MappedMetaModel(this, dataContextType, this.map); } ////// Create a mapping source from xml string. /// /// The type of DataContext to base the mapping on. /// A string containing XML. ///The mapping source. public static XmlMappingSource FromXml(string xml) { if (xml == null) { throw Error.ArgumentNull("xml"); } XmlReader reader = new XmlTextReader(new System.IO.StringReader(xml)); return FromReader(reader); } ////// Create a mapping source from xml reader. /// /// The type of DataContext to base the mapping on. /// An xml reader. ///The mapping source. public static XmlMappingSource FromReader(XmlReader reader) { if (reader == null) { throw Error.ArgumentNull("reader"); } reader.MoveToContent(); DatabaseMapping db = XmlMappingReader.ReadDatabaseMapping(reader); if (db == null) { throw Error.DatabaseNodeNotFound(XmlMappingConstant.MappingNamespace); } return new XmlMappingSource(db); } ////// Create a mapping source from xml in a stream. /// /// The type of DataContext to base the mapping on. /// A stream of xml. ///The mapping source. public static XmlMappingSource FromStream(System.IO.Stream stream) { if (stream == null) { throw Error.ArgumentNull("stream"); } XmlReader reader = new XmlTextReader(stream); return FromReader(reader); } ////// Create a mapping source from xml loaded from a url. /// /// The type of DataContext to base the mapping on. /// The Url pointing to the xml. ///The mapping source. [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", Justification="Unknown reason.")] public static XmlMappingSource FromUrl(string url) { if (url == null) { throw Error.ArgumentNull("url"); } XmlReader reader = new XmlTextReader(url); try { return FromReader(reader); } finally { reader.Close(); } } } class XmlMappingReader { private static string RequiredAttribute(XmlReader reader, string attribute) { string result = OptionalAttribute(reader, attribute); if (result == null) { throw Error.CouldNotFindRequiredAttribute(attribute, reader.ReadOuterXml()); } return result; } private static string OptionalAttribute(XmlReader reader, string attribute) { return reader.GetAttribute(attribute); } private static bool OptionalBoolAttribute(XmlReader reader, string attribute, bool @default) { string value = OptionalAttribute(reader, attribute); return (value != null) ? bool.Parse(value) : @default; } private static bool? OptionalNullableBoolAttribute(XmlReader reader, string attribute) { string value = OptionalAttribute(reader, attribute); return (value != null) ? (bool?)bool.Parse(value) : null; } private static void AssertEmptyElement(XmlReader reader) { if (!reader.IsEmptyElement) { string nodeName = reader.Name; reader.Read(); if (reader.NodeType != XmlNodeType.EndElement) { throw Error.ExpectedEmptyElement(nodeName, reader.NodeType, reader.Name); } } reader.Skip(); } internal static DatabaseMapping ReadDatabaseMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Database) { return null; } ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.Provider }); DatabaseMapping dm = new DatabaseMapping(); dm.DatabaseName = RequiredAttribute(reader, XmlMappingConstant.Name); dm.Provider = OptionalAttribute(reader, XmlMappingConstant.Provider); if (!reader.IsEmptyElement) { reader.ReadStartElement(); reader.MoveToContent(); while (reader.NodeType != XmlNodeType.EndElement) { if (reader.NodeType == XmlNodeType.Whitespace || !IsInNamespace(reader)) { reader.Skip(); continue; } switch (reader.LocalName) { case XmlMappingConstant.Table: dm.Tables.Add(ReadTableMapping(reader)); break; case XmlMappingConstant.Function: dm.Functions.Add(ReadFunctionMapping(reader)); break; default: throw Error.UnrecognizedElement(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } reader.MoveToContent(); } if (reader.LocalName != XmlMappingConstant.Database) { throw Error.UnexpectedElement(XmlMappingConstant.Database, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } reader.ReadEndElement(); } else { System.Diagnostics.Debug.Assert(false, "DatabaseMapping has no content"); reader.Skip(); } return dm; } internal static bool IsInNamespace(XmlReader reader) { return reader.LookupNamespace(reader.Prefix) == XmlMappingConstant.MappingNamespace; } internal static void ValidateAttributes(XmlReader reader, string[] validAttributes) { if (reader.HasAttributes) { ListattrList = new List (validAttributes); const string xmlns = "xmlns"; for (int i = 0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); // if the node's in the namespace, it is required to be one of the valid ones if (IsInNamespace(reader) && reader.LocalName != xmlns && !attrList.Contains(reader.LocalName)) { throw Error.UnrecognizedAttribute(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : ":", reader.LocalName)); } } reader.MoveToElement(); // Moves the reader back to the element node. } } internal static FunctionMapping ReadFunctionMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Function) { throw Error.UnexpectedElement(XmlMappingConstant.Function, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.Method, XmlMappingConstant.IsComposable }); FunctionMapping fm = new FunctionMapping(); fm.MethodName = RequiredAttribute(reader, XmlMappingConstant.Method); fm.Name = OptionalAttribute(reader, XmlMappingConstant.Name); fm.IsComposable = OptionalBoolAttribute(reader, XmlMappingConstant.IsComposable, false); if (!reader.IsEmptyElement) { reader.ReadStartElement(); reader.MoveToContent(); while (reader.NodeType != XmlNodeType.EndElement) { if (reader.NodeType == XmlNodeType.Whitespace || !IsInNamespace(reader)) { reader.Skip(); continue; } switch (reader.LocalName) { case XmlMappingConstant.Parameter: fm.Parameters.Add(ReadParameterMapping(reader)); break; case XmlMappingConstant.ElementType: fm.Types.Add(ReadElementTypeMapping(null, reader)); break; case XmlMappingConstant.Return: fm.FunReturn = ReadReturnMapping(reader); break; default: throw Error.UnrecognizedElement(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } reader.MoveToContent(); } reader.ReadEndElement(); } else { // no content is okay reader.Skip(); } return fm; } private static ReturnMapping ReadReturnMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Return) { throw Error.UnexpectedElement(XmlMappingConstant.Return, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } ValidateAttributes(reader, new[] { XmlMappingConstant.DbType }); ReturnMapping rm = new ReturnMapping(); rm.DbType = OptionalAttribute(reader, XmlMappingConstant.DbType); AssertEmptyElement(reader); return rm; } private static ParameterMapping ReadParameterMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Parameter) { throw Error.UnexpectedElement(XmlMappingConstant.Parameter, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.DbType, XmlMappingConstant.Parameter, XmlMappingConstant.Direction }); ParameterMapping pm = new ParameterMapping(); pm.Name = RequiredAttribute(reader, XmlMappingConstant.Name); pm.ParameterName = RequiredAttribute(reader, XmlMappingConstant.Parameter); pm.DbType = OptionalAttribute(reader, XmlMappingConstant.DbType); pm.XmlDirection = OptionalAttribute(reader, XmlMappingConstant.Direction); AssertEmptyElement(reader); return pm; } private static TableMapping ReadTableMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Table) { throw Error.UnexpectedElement(XmlMappingConstant.Table, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.Member }); TableMapping tm = new TableMapping(); tm.TableName = OptionalAttribute(reader, XmlMappingConstant.Name); tm.Member = OptionalAttribute(reader, XmlMappingConstant.Member); if (!reader.IsEmptyElement) { reader.ReadStartElement(); reader.MoveToContent(); while (reader.NodeType != XmlNodeType.EndElement) { if (reader.NodeType == XmlNodeType.Whitespace || !IsInNamespace(reader)) { reader.Skip(); continue; } switch (reader.LocalName) { case XmlMappingConstant.Type: if (tm.RowType != null) { goto default; } tm.RowType = ReadTypeMapping(null, reader); break; default: throw Error.UnrecognizedElement(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } reader.MoveToContent(); } if (reader.LocalName != XmlMappingConstant.Table) { throw Error.UnexpectedElement(XmlMappingConstant.Table, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } reader.ReadEndElement(); } else { System.Diagnostics.Debug.Assert(false, "Table has no content"); reader.Skip(); } return tm; } private static TypeMapping ReadElementTypeMapping(TypeMapping baseType, XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.ElementType) { throw Error.UnexpectedElement(XmlMappingConstant.Type, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } return ReadTypeMappingImpl(baseType, reader); } private static TypeMapping ReadTypeMapping(TypeMapping baseType, XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Type) { throw Error.UnexpectedElement(XmlMappingConstant.Type, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } return ReadTypeMappingImpl(baseType, reader); } private static TypeMapping ReadTypeMappingImpl(TypeMapping baseType, XmlReader reader) { ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.InheritanceCode, XmlMappingConstant.IsInheritanceDefault }); TypeMapping tm = new TypeMapping(); tm.BaseType = baseType; tm.Name = RequiredAttribute(reader, XmlMappingConstant.Name); tm.InheritanceCode = OptionalAttribute(reader, XmlMappingConstant.InheritanceCode); tm.IsInheritanceDefault = OptionalBoolAttribute(reader, XmlMappingConstant.IsInheritanceDefault, false); if (!reader.IsEmptyElement) { reader.ReadStartElement(); reader.MoveToContent(); while (reader.NodeType != XmlNodeType.EndElement) { if (reader.NodeType == XmlNodeType.Whitespace || !IsInNamespace(reader)) { reader.Skip(); continue; } switch (reader.LocalName) { case XmlMappingConstant.Type: tm.DerivedTypes.Add(ReadTypeMapping(tm, reader)); break; case XmlMappingConstant.Association: tm.Members.Add(ReadAssociationMapping(reader)); break; case XmlMappingConstant.Column: tm.Members.Add(ReadColumnMapping(reader)); break; default: throw Error.UnrecognizedElement(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } reader.MoveToContent(); } reader.ReadEndElement(); } else { // no content is okay reader.Skip(); } return tm; } private static AssociationMapping ReadAssociationMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Association) { throw Error.UnexpectedElement(XmlMappingConstant.Association, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.IsForeignKey, XmlMappingConstant.IsUnique, XmlMappingConstant.Member, XmlMappingConstant.OtherKey, XmlMappingConstant.Storage, XmlMappingConstant.ThisKey, XmlMappingConstant.DeleteRule, XmlMappingConstant.DeleteOnNull, }); AssociationMapping am = new AssociationMapping(); am.DbName = OptionalAttribute(reader, XmlMappingConstant.Name); am.IsForeignKey = OptionalBoolAttribute(reader, XmlMappingConstant.IsForeignKey, false); am.IsUnique = OptionalBoolAttribute(reader, XmlMappingConstant.IsUnique, false); am.MemberName = RequiredAttribute(reader, XmlMappingConstant.Member); am.OtherKey = OptionalAttribute(reader, XmlMappingConstant.OtherKey); am.StorageMemberName = OptionalAttribute(reader, XmlMappingConstant.Storage); am.ThisKey = OptionalAttribute(reader, XmlMappingConstant.ThisKey); am.DeleteRule = OptionalAttribute(reader, XmlMappingConstant.DeleteRule); am.DeleteOnNull = OptionalBoolAttribute(reader, XmlMappingConstant.DeleteOnNull, false); AssertEmptyElement(reader); return am; } private static ColumnMapping ReadColumnMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Column) { throw Error.UnexpectedElement(XmlMappingConstant.Column, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.DbType, XmlMappingConstant.IsDbGenerated, XmlMappingConstant.IsDiscriminator, XmlMappingConstant.IsPrimaryKey, XmlMappingConstant.IsVersion, XmlMappingConstant.Member, XmlMappingConstant.Storage, XmlMappingConstant.Expression, XmlMappingConstant.CanBeNull, XmlMappingConstant.UpdateCheck, XmlMappingConstant.AutoSync }); ColumnMapping cm = new ColumnMapping(); cm.DbName = OptionalAttribute(reader, XmlMappingConstant.Name); cm.DbType = OptionalAttribute(reader, XmlMappingConstant.DbType); cm.IsDbGenerated = OptionalBoolAttribute(reader, XmlMappingConstant.IsDbGenerated, false); cm.IsDiscriminator = OptionalBoolAttribute(reader, XmlMappingConstant.IsDiscriminator, false); cm.IsPrimaryKey = OptionalBoolAttribute(reader, XmlMappingConstant.IsPrimaryKey, false); cm.IsVersion = OptionalBoolAttribute(reader, XmlMappingConstant.IsVersion, false); cm.MemberName = RequiredAttribute(reader, XmlMappingConstant.Member); cm.StorageMemberName = OptionalAttribute(reader, XmlMappingConstant.Storage); cm.Expression = OptionalAttribute(reader, XmlMappingConstant.Expression); cm.CanBeNull = OptionalNullableBoolAttribute(reader, XmlMappingConstant.CanBeNull); string updateCheck = OptionalAttribute(reader, XmlMappingConstant.UpdateCheck); cm.UpdateCheck = (updateCheck == null) ? UpdateCheck.Always : (UpdateCheck)Enum.Parse(typeof(UpdateCheck), updateCheck); string autoSync = OptionalAttribute(reader, XmlMappingConstant.AutoSync); cm.AutoSync = (autoSync == null) ? AutoSync.Default : (AutoSync)Enum.Parse(typeof(AutoSync), autoSync); AssertEmptyElement(reader); return cm; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq.Expressions; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Xml; using System.Xml.Serialization; using LinqToSqlShared.Mapping; namespace System.Data.Linq.Mapping { using System.Data.Linq.Provider; using System.Diagnostics.CodeAnalysis; /// /// Represents a source for mapping information. /// public abstract class MappingSource { MetaModel primaryModel; ReaderWriterLock rwlock; DictionarysecondaryModels; /// /// Gets the MetaModel representing a DataContext and all it's /// accessible tables, functions and entities. /// public MetaModel GetModel(Type dataContextType) { if (dataContextType == null) { throw Error.ArgumentNull("dataContextType"); } MetaModel model = null; if (this.primaryModel == null) { model = this.CreateModel(dataContextType); Interlocked.CompareExchange(ref this.primaryModel, model, null); } // if the primary one matches, use it! if (this.primaryModel.ContextType == dataContextType) { return this.primaryModel; } // the rest of this only happens if you are using the mapping source for // more than one context type // build a map if one is not already defined if (this.secondaryModels == null) { Interlocked.CompareExchange >(ref this.secondaryModels, new Dictionary (), null); } // if we haven't created a read/writer lock, make one now if (this.rwlock == null) { Interlocked.CompareExchange (ref this.rwlock, new ReaderWriterLock(), null); } // lock the map and look inside MetaModel foundModel; this.rwlock.AcquireReaderLock(Timeout.Infinite); try { if (this.secondaryModels.TryGetValue(dataContextType, out foundModel)) { return foundModel; } } finally { this.rwlock.ReleaseReaderLock(); } // if it wasn't found, lock for write and try again this.rwlock.AcquireWriterLock(Timeout.Infinite); try { if (this.secondaryModels.TryGetValue(dataContextType, out foundModel)) { return foundModel; } if (model == null) { model = this.CreateModel(dataContextType); } this.secondaryModels.Add(dataContextType, model); } finally { this.rwlock.ReleaseWriterLock(); } return model; } /// /// Creates a new instance of a MetaModel. This method is called by GetModel(). /// Override this method when defining a new type of MappingSource. /// /// ///protected abstract MetaModel CreateModel(Type dataContextType); } /// /// A mapping source that uses attributes on the context to create the mapping model. /// public sealed class AttributeMappingSource : MappingSource { public AttributeMappingSource() { } protected override MetaModel CreateModel(Type dataContextType) { if (dataContextType == null) { throw Error.ArgumentNull("dataContextType"); } return new AttributedMetaModel(this, dataContextType); } } ////// A mapping source that uses an external XML mapping source to create the model. /// public sealed class XmlMappingSource : MappingSource { DatabaseMapping map; private XmlMappingSource(DatabaseMapping map) { this.map = map; } protected override MetaModel CreateModel(Type dataContextType) { if (dataContextType == null) { throw Error.ArgumentNull("dataContextType"); } return new MappedMetaModel(this, dataContextType, this.map); } ////// Create a mapping source from xml string. /// /// The type of DataContext to base the mapping on. /// A string containing XML. ///The mapping source. public static XmlMappingSource FromXml(string xml) { if (xml == null) { throw Error.ArgumentNull("xml"); } XmlReader reader = new XmlTextReader(new System.IO.StringReader(xml)); return FromReader(reader); } ////// Create a mapping source from xml reader. /// /// The type of DataContext to base the mapping on. /// An xml reader. ///The mapping source. public static XmlMappingSource FromReader(XmlReader reader) { if (reader == null) { throw Error.ArgumentNull("reader"); } reader.MoveToContent(); DatabaseMapping db = XmlMappingReader.ReadDatabaseMapping(reader); if (db == null) { throw Error.DatabaseNodeNotFound(XmlMappingConstant.MappingNamespace); } return new XmlMappingSource(db); } ////// Create a mapping source from xml in a stream. /// /// The type of DataContext to base the mapping on. /// A stream of xml. ///The mapping source. public static XmlMappingSource FromStream(System.IO.Stream stream) { if (stream == null) { throw Error.ArgumentNull("stream"); } XmlReader reader = new XmlTextReader(stream); return FromReader(reader); } ////// Create a mapping source from xml loaded from a url. /// /// The type of DataContext to base the mapping on. /// The Url pointing to the xml. ///The mapping source. [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", Justification="Unknown reason.")] public static XmlMappingSource FromUrl(string url) { if (url == null) { throw Error.ArgumentNull("url"); } XmlReader reader = new XmlTextReader(url); try { return FromReader(reader); } finally { reader.Close(); } } } class XmlMappingReader { private static string RequiredAttribute(XmlReader reader, string attribute) { string result = OptionalAttribute(reader, attribute); if (result == null) { throw Error.CouldNotFindRequiredAttribute(attribute, reader.ReadOuterXml()); } return result; } private static string OptionalAttribute(XmlReader reader, string attribute) { return reader.GetAttribute(attribute); } private static bool OptionalBoolAttribute(XmlReader reader, string attribute, bool @default) { string value = OptionalAttribute(reader, attribute); return (value != null) ? bool.Parse(value) : @default; } private static bool? OptionalNullableBoolAttribute(XmlReader reader, string attribute) { string value = OptionalAttribute(reader, attribute); return (value != null) ? (bool?)bool.Parse(value) : null; } private static void AssertEmptyElement(XmlReader reader) { if (!reader.IsEmptyElement) { string nodeName = reader.Name; reader.Read(); if (reader.NodeType != XmlNodeType.EndElement) { throw Error.ExpectedEmptyElement(nodeName, reader.NodeType, reader.Name); } } reader.Skip(); } internal static DatabaseMapping ReadDatabaseMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Database) { return null; } ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.Provider }); DatabaseMapping dm = new DatabaseMapping(); dm.DatabaseName = RequiredAttribute(reader, XmlMappingConstant.Name); dm.Provider = OptionalAttribute(reader, XmlMappingConstant.Provider); if (!reader.IsEmptyElement) { reader.ReadStartElement(); reader.MoveToContent(); while (reader.NodeType != XmlNodeType.EndElement) { if (reader.NodeType == XmlNodeType.Whitespace || !IsInNamespace(reader)) { reader.Skip(); continue; } switch (reader.LocalName) { case XmlMappingConstant.Table: dm.Tables.Add(ReadTableMapping(reader)); break; case XmlMappingConstant.Function: dm.Functions.Add(ReadFunctionMapping(reader)); break; default: throw Error.UnrecognizedElement(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } reader.MoveToContent(); } if (reader.LocalName != XmlMappingConstant.Database) { throw Error.UnexpectedElement(XmlMappingConstant.Database, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } reader.ReadEndElement(); } else { System.Diagnostics.Debug.Assert(false, "DatabaseMapping has no content"); reader.Skip(); } return dm; } internal static bool IsInNamespace(XmlReader reader) { return reader.LookupNamespace(reader.Prefix) == XmlMappingConstant.MappingNamespace; } internal static void ValidateAttributes(XmlReader reader, string[] validAttributes) { if (reader.HasAttributes) { ListattrList = new List (validAttributes); const string xmlns = "xmlns"; for (int i = 0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); // if the node's in the namespace, it is required to be one of the valid ones if (IsInNamespace(reader) && reader.LocalName != xmlns && !attrList.Contains(reader.LocalName)) { throw Error.UnrecognizedAttribute(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : ":", reader.LocalName)); } } reader.MoveToElement(); // Moves the reader back to the element node. } } internal static FunctionMapping ReadFunctionMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Function) { throw Error.UnexpectedElement(XmlMappingConstant.Function, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.Method, XmlMappingConstant.IsComposable }); FunctionMapping fm = new FunctionMapping(); fm.MethodName = RequiredAttribute(reader, XmlMappingConstant.Method); fm.Name = OptionalAttribute(reader, XmlMappingConstant.Name); fm.IsComposable = OptionalBoolAttribute(reader, XmlMappingConstant.IsComposable, false); if (!reader.IsEmptyElement) { reader.ReadStartElement(); reader.MoveToContent(); while (reader.NodeType != XmlNodeType.EndElement) { if (reader.NodeType == XmlNodeType.Whitespace || !IsInNamespace(reader)) { reader.Skip(); continue; } switch (reader.LocalName) { case XmlMappingConstant.Parameter: fm.Parameters.Add(ReadParameterMapping(reader)); break; case XmlMappingConstant.ElementType: fm.Types.Add(ReadElementTypeMapping(null, reader)); break; case XmlMappingConstant.Return: fm.FunReturn = ReadReturnMapping(reader); break; default: throw Error.UnrecognizedElement(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } reader.MoveToContent(); } reader.ReadEndElement(); } else { // no content is okay reader.Skip(); } return fm; } private static ReturnMapping ReadReturnMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Return) { throw Error.UnexpectedElement(XmlMappingConstant.Return, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } ValidateAttributes(reader, new[] { XmlMappingConstant.DbType }); ReturnMapping rm = new ReturnMapping(); rm.DbType = OptionalAttribute(reader, XmlMappingConstant.DbType); AssertEmptyElement(reader); return rm; } private static ParameterMapping ReadParameterMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Parameter) { throw Error.UnexpectedElement(XmlMappingConstant.Parameter, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.DbType, XmlMappingConstant.Parameter, XmlMappingConstant.Direction }); ParameterMapping pm = new ParameterMapping(); pm.Name = RequiredAttribute(reader, XmlMappingConstant.Name); pm.ParameterName = RequiredAttribute(reader, XmlMappingConstant.Parameter); pm.DbType = OptionalAttribute(reader, XmlMappingConstant.DbType); pm.XmlDirection = OptionalAttribute(reader, XmlMappingConstant.Direction); AssertEmptyElement(reader); return pm; } private static TableMapping ReadTableMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Table) { throw Error.UnexpectedElement(XmlMappingConstant.Table, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.Member }); TableMapping tm = new TableMapping(); tm.TableName = OptionalAttribute(reader, XmlMappingConstant.Name); tm.Member = OptionalAttribute(reader, XmlMappingConstant.Member); if (!reader.IsEmptyElement) { reader.ReadStartElement(); reader.MoveToContent(); while (reader.NodeType != XmlNodeType.EndElement) { if (reader.NodeType == XmlNodeType.Whitespace || !IsInNamespace(reader)) { reader.Skip(); continue; } switch (reader.LocalName) { case XmlMappingConstant.Type: if (tm.RowType != null) { goto default; } tm.RowType = ReadTypeMapping(null, reader); break; default: throw Error.UnrecognizedElement(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } reader.MoveToContent(); } if (reader.LocalName != XmlMappingConstant.Table) { throw Error.UnexpectedElement(XmlMappingConstant.Table, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } reader.ReadEndElement(); } else { System.Diagnostics.Debug.Assert(false, "Table has no content"); reader.Skip(); } return tm; } private static TypeMapping ReadElementTypeMapping(TypeMapping baseType, XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.ElementType) { throw Error.UnexpectedElement(XmlMappingConstant.Type, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } return ReadTypeMappingImpl(baseType, reader); } private static TypeMapping ReadTypeMapping(TypeMapping baseType, XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Type) { throw Error.UnexpectedElement(XmlMappingConstant.Type, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } return ReadTypeMappingImpl(baseType, reader); } private static TypeMapping ReadTypeMappingImpl(TypeMapping baseType, XmlReader reader) { ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.InheritanceCode, XmlMappingConstant.IsInheritanceDefault }); TypeMapping tm = new TypeMapping(); tm.BaseType = baseType; tm.Name = RequiredAttribute(reader, XmlMappingConstant.Name); tm.InheritanceCode = OptionalAttribute(reader, XmlMappingConstant.InheritanceCode); tm.IsInheritanceDefault = OptionalBoolAttribute(reader, XmlMappingConstant.IsInheritanceDefault, false); if (!reader.IsEmptyElement) { reader.ReadStartElement(); reader.MoveToContent(); while (reader.NodeType != XmlNodeType.EndElement) { if (reader.NodeType == XmlNodeType.Whitespace || !IsInNamespace(reader)) { reader.Skip(); continue; } switch (reader.LocalName) { case XmlMappingConstant.Type: tm.DerivedTypes.Add(ReadTypeMapping(tm, reader)); break; case XmlMappingConstant.Association: tm.Members.Add(ReadAssociationMapping(reader)); break; case XmlMappingConstant.Column: tm.Members.Add(ReadColumnMapping(reader)); break; default: throw Error.UnrecognizedElement(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } reader.MoveToContent(); } reader.ReadEndElement(); } else { // no content is okay reader.Skip(); } return tm; } private static AssociationMapping ReadAssociationMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Association) { throw Error.UnexpectedElement(XmlMappingConstant.Association, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.IsForeignKey, XmlMappingConstant.IsUnique, XmlMappingConstant.Member, XmlMappingConstant.OtherKey, XmlMappingConstant.Storage, XmlMappingConstant.ThisKey, XmlMappingConstant.DeleteRule, XmlMappingConstant.DeleteOnNull, }); AssociationMapping am = new AssociationMapping(); am.DbName = OptionalAttribute(reader, XmlMappingConstant.Name); am.IsForeignKey = OptionalBoolAttribute(reader, XmlMappingConstant.IsForeignKey, false); am.IsUnique = OptionalBoolAttribute(reader, XmlMappingConstant.IsUnique, false); am.MemberName = RequiredAttribute(reader, XmlMappingConstant.Member); am.OtherKey = OptionalAttribute(reader, XmlMappingConstant.OtherKey); am.StorageMemberName = OptionalAttribute(reader, XmlMappingConstant.Storage); am.ThisKey = OptionalAttribute(reader, XmlMappingConstant.ThisKey); am.DeleteRule = OptionalAttribute(reader, XmlMappingConstant.DeleteRule); am.DeleteOnNull = OptionalBoolAttribute(reader, XmlMappingConstant.DeleteOnNull, false); AssertEmptyElement(reader); return am; } private static ColumnMapping ReadColumnMapping(XmlReader reader) { System.Diagnostics.Debug.Assert(reader.NodeType == XmlNodeType.Element); if (!IsInNamespace(reader) || reader.LocalName != XmlMappingConstant.Column) { throw Error.UnexpectedElement(XmlMappingConstant.Column, String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}{2}", reader.Prefix, String.IsNullOrEmpty(reader.Prefix) ? "" : "/", reader.LocalName)); } ValidateAttributes(reader, new[] { XmlMappingConstant.Name, XmlMappingConstant.DbType, XmlMappingConstant.IsDbGenerated, XmlMappingConstant.IsDiscriminator, XmlMappingConstant.IsPrimaryKey, XmlMappingConstant.IsVersion, XmlMappingConstant.Member, XmlMappingConstant.Storage, XmlMappingConstant.Expression, XmlMappingConstant.CanBeNull, XmlMappingConstant.UpdateCheck, XmlMappingConstant.AutoSync }); ColumnMapping cm = new ColumnMapping(); cm.DbName = OptionalAttribute(reader, XmlMappingConstant.Name); cm.DbType = OptionalAttribute(reader, XmlMappingConstant.DbType); cm.IsDbGenerated = OptionalBoolAttribute(reader, XmlMappingConstant.IsDbGenerated, false); cm.IsDiscriminator = OptionalBoolAttribute(reader, XmlMappingConstant.IsDiscriminator, false); cm.IsPrimaryKey = OptionalBoolAttribute(reader, XmlMappingConstant.IsPrimaryKey, false); cm.IsVersion = OptionalBoolAttribute(reader, XmlMappingConstant.IsVersion, false); cm.MemberName = RequiredAttribute(reader, XmlMappingConstant.Member); cm.StorageMemberName = OptionalAttribute(reader, XmlMappingConstant.Storage); cm.Expression = OptionalAttribute(reader, XmlMappingConstant.Expression); cm.CanBeNull = OptionalNullableBoolAttribute(reader, XmlMappingConstant.CanBeNull); string updateCheck = OptionalAttribute(reader, XmlMappingConstant.UpdateCheck); cm.UpdateCheck = (updateCheck == null) ? UpdateCheck.Always : (UpdateCheck)Enum.Parse(typeof(UpdateCheck), updateCheck); string autoSync = OptionalAttribute(reader, XmlMappingConstant.AutoSync); cm.AutoSync = (autoSync == null) ? AutoSync.Default : (AutoSync)Enum.Parse(typeof(AutoSync), autoSync); AssertEmptyElement(reader); return cm; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WinHttpWebProxyFinder.cs
- SQLByte.cs
- PowerModeChangedEventArgs.cs
- CurrentChangingEventManager.cs
- FacetEnabledSchemaElement.cs
- ErrorReporting.cs
- TextCompositionManager.cs
- RuntimeHelpers.cs
- AnnotationHighlightLayer.cs
- Screen.cs
- SqlDataReaderSmi.cs
- DispatcherHookEventArgs.cs
- SortQuery.cs
- FactoryGenerator.cs
- ToolboxService.cs
- BitmapEffectGroup.cs
- Soap.cs
- RequiredFieldValidator.cs
- XmlWriterSettings.cs
- SimpleHandlerBuildProvider.cs
- HttpPostLocalhostServerProtocol.cs
- SymbolEqualComparer.cs
- HttpServerVarsCollection.cs
- RequestQueryProcessor.cs
- EventDescriptor.cs
- NamedObject.cs
- InheritedPropertyDescriptor.cs
- SctClaimDictionary.cs
- XPathItem.cs
- VarInfo.cs
- SplitterCancelEvent.cs
- DataListItemCollection.cs
- ObjectDataSourceView.cs
- EntityParameterCollection.cs
- InputDevice.cs
- QilList.cs
- OdbcRowUpdatingEvent.cs
- ProxyManager.cs
- InteropBitmapSource.cs
- StringDictionary.cs
- SafeHandles.cs
- SynchronizedInputProviderWrapper.cs
- ObjectQueryState.cs
- MimeImporter.cs
- ChtmlSelectionListAdapter.cs
- StylusDownEventArgs.cs
- SqlConnectionHelper.cs
- AssemblyUtil.cs
- VariantWrapper.cs
- GenericEnumConverter.cs
- CryptographicAttribute.cs
- ErrorHandler.cs
- ImportOptions.cs
- DragDeltaEventArgs.cs
- ParseChildrenAsPropertiesAttribute.cs
- AliasGenerator.cs
- COM2Enum.cs
- DateBoldEvent.cs
- ObfuscateAssemblyAttribute.cs
- TypeViewSchema.cs
- TypeDescriptionProviderAttribute.cs
- VisemeEventArgs.cs
- ConstantSlot.cs
- GridViewUpdatedEventArgs.cs
- DataViewSettingCollection.cs
- ObjectStateEntry.cs
- BrowserDefinitionCollection.cs
- PrimitiveSchema.cs
- PolyQuadraticBezierSegment.cs
- FrameworkElement.cs
- SqlFileStream.cs
- DependencyProperty.cs
- cryptoapiTransform.cs
- BitmapEffectInputData.cs
- ICollection.cs
- ListChangedEventArgs.cs
- RootBuilder.cs
- PrivateFontCollection.cs
- TableHeaderCell.cs
- InstanceDataCollectionCollection.cs
- PackUriHelper.cs
- DataKeyArray.cs
- OdbcConnection.cs
- Vector3DAnimation.cs
- CryptoStream.cs
- ChangePasswordDesigner.cs
- ExpressionBuilderContext.cs
- ObjectListDataBindEventArgs.cs
- SolidColorBrush.cs
- Closure.cs
- DynamicRouteExpression.cs
- ViewBase.cs
- SpecularMaterial.cs
- RandomNumberGenerator.cs
- Rules.cs
- SizeLimitedCache.cs
- PropertyGridEditorPart.cs
- FirstMatchCodeGroup.cs
- OleDbInfoMessageEvent.cs
- StylusPointPropertyId.cs