MetadataItemSerializer.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntityDesign / Design / System / Data / Entity / Design / Common / MetadataItemSerializer.cs / 1 / MetadataItemSerializer.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 
using System;
using System.Data.Common; 
using System.Collections.Generic;
using System.Text;
using System.Data.Metadata.Edm;
using System.Reflection; 
using System.Diagnostics;
using System.Xml; 
using System.Globalization; 
using System.IO;
using System.Data.Entity.Design.SsdlGenerator; 
using System.Linq;

namespace System.Data.Entity.Design.Common
{ 
    /// 
    /// This class is reponsible for serailizing Edm Metadata out to the appropriate file .csdl or .ssdl 
    ///  
    internal class MetadataItemSerializer
    { 
        public static readonly EdmType NoSpecificTypeSentinal = MetadataItem.GetBuiltInType(BuiltInTypeKind.EdmType);

        private bool _isModel;
        private ErrorsLookup _errorsLookup; 
        private XmlWriter _writer;
        private MetadataItemSerializer(XmlWriter writer, bool isModel, ErrorsLookup errorsLookup) 
        { 
            _writer = writer;
            _isModel = isModel; 
            _errorsLookup = errorsLookup;
        }

        public class ErrorsLookup : Dictionary> { } 

        internal readonly string EdmNamespace = "Edm"; 
 
        public static void WriteXml(XmlWriter writer, ItemCollection collection, string namespaceToWrite, params KeyValuePair [] xmlPrefixToNamespaces)
        { 
            WriteXml(writer, collection, namespaceToWrite, new ErrorsLookup(), new List(), null, null, xmlPrefixToNamespaces);
        }

        internal static void WriteXml(XmlWriter writer, ItemCollection collection, string namespaceToWrite, ErrorsLookup errorsLookup, List commentedOutItems, string provider, string providerManifestToken, params KeyValuePair[] xmlPrefixToNamespaces) 
        {
            Debug.Assert(writer != null, "writer parameter is null"); 
            Debug.Assert(collection != null, "collection parameter is null"); 
            Debug.Assert(errorsLookup != null, "errorsLookup parameter is null");
            Debug.Assert(!string.IsNullOrEmpty(namespaceToWrite), "namespaceToWrite parameter is null or empty"); 

            MetadataItemSerializer serializer = new MetadataItemSerializer(writer, collection.DataSpace == DataSpace.CSpace, errorsLookup);

            serializer.ValidateNamespace(namespaceToWrite); 
            serializer.WriteSchemaElement(namespaceToWrite, provider, providerManifestToken, xmlPrefixToNamespaces);
            serializer.WriteErrorsComment(NoSpecificTypeSentinal); 
            foreach (EntityContainer item in collection.GetItems()) 
            {
                serializer.WriteEntityContainerElement(item); 
            }

            foreach (EdmType type in collection.GetItems())
            { 
                // is it in the right space (c or s)
                // does it have the right namespace? 
                if (type.NamespaceName == namespaceToWrite) 
                {
                    serializer.WriteTypeElement(type); 
                }
            }

            if(commentedOutItems.Count > 0) 
            {
                StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture); 
                XmlWriterSettings settings = new XmlWriterSettings(); 
                settings.Indent = true;
                settings.OmitXmlDeclaration = true; 
                // we can have more than one commented out type
                // which will look like multiple root elements, so this is a fragment
                settings.ConformanceLevel = ConformanceLevel.Fragment;
                XmlWriter commentWriter = XmlWriter.Create(stringWriter, settings); 
                MetadataItemSerializer commmentSerializer = new MetadataItemSerializer(commentWriter, collection.DataSpace == DataSpace.CSpace, errorsLookup);
                foreach (EdmType type in commentedOutItems) 
                { 
                    commmentSerializer.WriteTypeElement(type);
                } 
                commentWriter.Flush();
                //This is not the cleanest thing to do but XmlTextWriter
                //does not allow writing xml comment characters while writing a comment.
                //and since we know exactly the string we write, this is pretty safe. 
                string comment = RemoveXmlCommentCharacters(stringWriter);
                writer.WriteComment(comment); 
            } 
            writer.WriteEndElement();
        } 

        private static string RemoveXmlCommentCharacters(StringWriter stringWriter)
        {
            string comment = stringWriter.GetStringBuilder().ToString(); 
            while (comment.Contains(XmlConstants.XmlCommentStartString))
            { 
                comment = comment.Replace(XmlConstants.XmlCommentStartString, String.Empty); 
            }
            while (comment.Contains(XmlConstants.XmlCommentEndString)) 
            {
                comment = comment.Replace(XmlConstants.XmlCommentEndString, String.Empty);
            }
            return comment; 
        }
 
        private void ValidateNamespace(string namespaceToWrite) 
        {
            if (EdmItemCollection.IsSystemNamespace(MetadataItem.EdmProviderManifest, namespaceToWrite)) 
            {
                throw EDesignUtil.EdmReservedNamespace(namespaceToWrite);
            }
        } 

        private void WriteTypeElement(EdmType type) 
        { 
            WriteErrorsComment(type);
            switch (type.BuiltInTypeKind) 
            {
                case BuiltInTypeKind.EntityType:
                    WriteEntityTypeElement((EntityType)type);
                    break; 
                case BuiltInTypeKind.AssociationType:
                    WriteAssociationTypeElement((AssociationType)type); 
                    break; 
                case BuiltInTypeKind.EdmFunction:
                    Debug.Assert(!_isModel, "we only expect functions in sspace"); 
                    WriteFunctionElement((EdmFunction)type);
                    break;
                case BuiltInTypeKind.ComplexType:
                    WriteComplexTypeElement((ComplexType)type); 
                    break;
                default: 
                    throw EDesignUtil.NonSerializableType(type.BuiltInTypeKind); 
            }
        } 

        private void WriteFunctionElement(EdmFunction function)
        {
            _writer.WriteStartElement(XmlConstants.Function); 
            _writer.WriteAttributeString(XmlConstants.Name, function.Name);
            if (function.ReturnParameter != null) 
            { 
                _writer.WriteAttributeString(XmlConstants.ReturnType, GetFullName(function.ReturnParameter.TypeUsage.EdmType));
            } 
            _writer.WriteAttributeString(XmlConstants.AggregateAttribute, GetAttributeValueString(function.AggregateAttribute));
            _writer.WriteAttributeString(XmlConstants.BuiltInAttribute, GetAttributeValueString(function.BuiltInAttribute));
            _writer.WriteAttributeString(XmlConstants.NiladicFunction, GetAttributeValueString(function.NiladicFunctionAttribute));
            _writer.WriteAttributeString(XmlConstants.IsComposable, GetAttributeValueString(function.IsComposableAttribute)); 
            _writer.WriteAttributeString(XmlConstants.ParameterTypeSemantics, GetAttributeValueString(function.ParameterTypeSemanticsAttribute));
 
            if (function.StoreFunctionNameAttribute != null) 
            {
                _writer.WriteAttributeString(XmlConstants.StoreFunctionName, function.StoreFunctionNameAttribute); 
            }

            if(function.CommandTextAttribute != null)
            { 
                _writer.WriteAttributeString(XmlConstants.CommandText, function.CommandTextAttribute);
            } 
 
            if (function.Schema != null)
            { 
                _writer.WriteAttributeString(XmlConstants.Schema, function.Schema);
            }

            foreach (FunctionParameter parameter in function.Parameters) 
            {
                WriteFunctionParameterElement(parameter); 
            } 

            _writer.WriteEndElement(); 
        }

        private void WriteFunctionParameterElement(FunctionParameter parameter)
        { 
            _writer.WriteStartElement(XmlConstants.Parameter);
            _writer.WriteAttributeString(XmlConstants.Name, parameter.Name); 
            _writer.WriteAttributeString(XmlConstants.TypeAttribute, GetFullName(parameter.TypeUsage.EdmType)); 
            _writer.WriteAttributeString(XmlConstants.Mode, GetAttributeValueString(parameter.Mode));
            _writer.WriteEndElement(); 
        }


        private void WriteComplexTypeElement(ComplexType complexType) 
        {
            _writer.WriteStartElement(XmlConstants.ComplexType); 
            _writer.WriteAttributeString(XmlConstants.Name, complexType.Name); 
            if (complexType.BaseType != null)
            { 
                _writer.WriteAttributeString(XmlConstants.BaseType, GetFullName(complexType.BaseType));
            }

            foreach (EdmMember member in complexType.GetDeclaredOnlyMembers()) 
            {
                WritePropertyElement(member); 
            } 
            _writer.WriteEndElement();
        } 

        private void WriteAssociationTypeElement(AssociationType associationType)
        {
            _writer.WriteStartElement(XmlConstants.Association); 
            _writer.WriteAttributeString(XmlConstants.Name, associationType.Name);
            foreach (RelationshipEndMember end in associationType.RelationshipEndMembers) 
            { 
                WriteRelationshipEndElement(end);
            } 

            foreach (ReferentialConstraint constraint in associationType.ReferentialConstraints)
            {
                WriteReferentialConstraintElement(constraint); 
            }
 
            _writer.WriteEndElement(); 
        }
 
        private void WriteReferentialConstraintElement(ReferentialConstraint constraint)
        {
            _writer.WriteStartElement(XmlConstants.ReferentialConstraint);
            WriteReferentialConstraintRoleElement(XmlConstants.PrincipalRole, constraint.FromRole, constraint.FromProperties); 
            WriteReferentialConstraintRoleElement(XmlConstants.DependentRole, constraint.ToRole, constraint.ToProperties);
            _writer.WriteEndElement(); 
        } 

        private void WriteReferentialConstraintRoleElement(string nodeName, RelationshipEndMember end, IList properties) 
        {
            // Generate the principal and dependent role nodes
            _writer.WriteStartElement(nodeName);
            _writer.WriteAttributeString(XmlConstants.Role, end.Name); 
            for (int i = 0; i < properties.Count; i++)
            { 
                _writer.WriteStartElement(XmlConstants.PropertyRef); 
                _writer.WriteAttributeString(XmlConstants.Name, properties[i].Name);
                _writer.WriteEndElement(); 
            }
            _writer.WriteEndElement();
        }
 
        private void WriteRelationshipEndElement(RelationshipEndMember end)
        { 
            _writer.WriteStartElement(XmlConstants.End); 
            _writer.WriteAttributeString(XmlConstants.Role, end.Name);
 
            string typeName = GetFullName(((RefType)end.TypeUsage.EdmType).ElementType);
            _writer.WriteAttributeString(XmlConstants.TypeAttribute, typeName);
            _writer.WriteAttributeString(XmlConstants.Multiplicity, GetXmlMultiplicity(end.RelationshipMultiplicity));
            if (end.DeleteBehavior != OperationAction.None) 
            {
                WriteOperationActionElement(XmlConstants.OnDelete, end.DeleteBehavior); 
            } 
            _writer.WriteEndElement();
        } 

        private void WriteOperationActionElement(string elementName, OperationAction operationAction)
        {
            _writer.WriteStartElement(elementName); 
            _writer.WriteAttributeString(XmlConstants.Action, operationAction.ToString());
            _writer.WriteEndElement(); 
        } 

        private string GetXmlMultiplicity(RelationshipMultiplicity relationshipMultiplicity) 
        {
            switch(relationshipMultiplicity)
            {
                case RelationshipMultiplicity.Many: 
                    return "*";
                case RelationshipMultiplicity.One: 
                    return "1"; 
                case RelationshipMultiplicity.ZeroOrOne:
                    return "0..1"; 
                default:
                    Debug.Fail("Did you add a new RelationshipMultiplicity?");
                    return string.Empty;
            } 
        }
 
        private void WriteEntityTypeElement(EntityType entityType) 
        {
            _writer.WriteStartElement(XmlConstants.EntityType); 
            _writer.WriteAttributeString(XmlConstants.Name, entityType.Name);
            if (entityType.BaseType != null)
            {
                _writer.WriteAttributeString(XmlConstants.BaseType, GetFullName(entityType.BaseType)); 
            }
 
            if (entityType.Abstract) 
            {
                _writer.WriteAttributeString(XmlConstants.Abstract, XmlConstants.True); 
            }

            if (entityType.KeyMembers.Count != 0 &&
                entityType.KeyMembers[0].DeclaringType == entityType) // they are declared on this entity 
            {
                _writer.WriteStartElement(XmlConstants.Key); 
                for (int i = 0; i < entityType.KeyMembers.Count; i++) 
                {
                    _writer.WriteStartElement(XmlConstants.PropertyRef); 
                    _writer.WriteAttributeString(XmlConstants.Name, entityType.KeyMembers[i].Name);
                    _writer.WriteEndElement();
                }
                _writer.WriteEndElement(); 
            }
 
            foreach (EdmProperty member in entityType.GetDeclaredOnlyMembers()) 
            {
                WritePropertyElement(member); 
            }

            foreach (NavigationProperty navigationProperty in entityType.NavigationProperties )
            { 
                if (navigationProperty.DeclaringType == entityType)
                { 
                    WriteNavigationPropertyElement(navigationProperty); 
                }
            } 
            _writer.WriteEndElement();
        }

        private void WriteErrorsComment(EdmType type) 
        {
            List errors; 
            if (_errorsLookup.TryGetValue(type, out errors)) 
            {
                Debug.Assert(errors.Count > 0, "how did we get an empty errors collection?"); 

                StringBuilder builder = new StringBuilder();
                builder.AppendLine(Strings.MetadataItemErrorsFoundDuringGeneration);
                foreach (EdmSchemaError error in errors) 
                {
                    builder.AppendLine(error.ToString()); 
                } 
                _writer.WriteComment(builder.ToString());
            } 
        }

        private void WriteNavigationPropertyElement(NavigationProperty member)
        { 
            _writer.WriteStartElement(XmlConstants.NavigationProperty);
            _writer.WriteAttributeString(XmlConstants.Name, member.Name); 
            _writer.WriteAttributeString(XmlConstants.Relationship, member.RelationshipType.FullName); 
            _writer.WriteAttributeString(XmlConstants.FromRole, member.FromEndMember.Name);
            _writer.WriteAttributeString(XmlConstants.ToRole, member.ToEndMember.Name); 
            _writer.WriteEndElement();
        }

        private void WritePropertyElement(EdmMember member) 
        {
            _writer.WriteStartElement(XmlConstants.Property); 
            _writer.WriteAttributeString(XmlConstants.Name, member.Name); 
            _writer.WriteAttributeString(XmlConstants.TypeAttribute, GetTypeName(member.TypeUsage));
            WritePropertyTypeFacets(member.TypeUsage); 
            _writer.WriteEndElement();
        }

        private void WritePropertyTypeFacets(TypeUsage typeUsage) 
        {
            // we need to use the facets for this particular provider, not the ones that they type 
            // may have been converted to (think CSDL types converted to provider types) 
            EdmType type = GetEdmType(typeUsage);
            IEnumerable providerDescriptions = GetAssociatedFacetDescriptions(type); 

            foreach (Facet facet in typeUsage.Facets)
            {
                FacetDescription providerFacetDescription = null; 
                if (IsSpecialFacet(facet))
                { 
                    providerFacetDescription = facet.Description; 
                }
                else 
                {
                    foreach (FacetDescription description in providerDescriptions)
                    {
                        if (description.FacetName == facet.Name) 
                        {
                            providerFacetDescription = description; 
                            break; 
                        }
                    } 
                }

                //
                // Don't emit this facet if we shouldn't 
                //
                if (SkipFacet(facet, providerFacetDescription)) 
                { 
                    continue;
                } 

                //
                // Special case for MaxLength facet value of "Max"
                // 
                if (_isModel &&
                    type.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType) 
                { 
                    PrimitiveType primitiveType = (PrimitiveType)type;
 
                    if ((primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.String ||
                         primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.Binary) &&
                        facet.Name == DbProviderManifest.MaxLengthFacetName &&
                        Helper.IsUnboundedFacetValue(facet)) 
                    {
                        _writer.WriteAttributeString(TranslateFacetNameToAttributeName(facet.Name), XmlConstants.Max); 
                        continue; 
                    }
                } 

                _writer.WriteAttributeString(TranslateFacetNameToAttributeName(facet.Name), GetAttributeValueString(facet.Value));
            }
        } 

 
        private string TranslateFacetNameToAttributeName(string facetName) 
        {
            if(DbProviderManifest.DefaultValueFacetName == facetName) 
            {
                return XmlConstants.DefaultValueAttribute;
            }
 
            return facetName;
        } 
 
        /// 
        /// Should this facet be skipped ? 
        /// A facet should be skipped if it satsifies one of the following
        ///   - the providerFacetDescription is null - (ie) the provider knows of no such facet
        ///   - the facetDescription indicates that the facet must have a constant value
        ///   - the facet value is null 
        ///   - the facet value is the default value for the facet, and the facet is not required
        ///   - we're emitting a model schema, and the facet in question is one of the following 
        ///       - MaxLength, FixedLength, Unicode, Collation, Precision, Scale, DateTimeKind 
        /// 
        /// the facet in question 
        /// facet description in the provider
        /// true, if the facet should be skipped
        private bool SkipFacet(Facet facet, FacetDescription providerFacetDescription)
        { 
            //
            // if the provider doesn't recognize it, it will complain 
            // when it sees it; so don't put it in 
            //
            if (providerFacetDescription == null) 
            {
                return true;
            }
            // skip it if it is constant for the current provider 
            if (providerFacetDescription.IsConstant)
            { 
                return true; 
            }
 
            //
            // Null facets can and should be omitted
            //
            if (facet.Value == null) 
            {
                return true; 
            } 

            // 
            // skip if it is not required, and has the default value
            //
            if (!providerFacetDescription.IsRequired &&
                facet.Value.Equals(providerFacetDescription.DefaultValue)) 
            {
                return true; 
            } 

            return false; 
        }

        private bool IsSpecialFacet(Facet facet)
        { 
            if(_isModel)
            { 
                return (facet.Name == "ClientAutoGenerated" || 
                        facet.Name == EdmProviderManifest.ConcurrencyModeFacetName ||
                        facet.Name == "StoreGenerated" || 
                        facet.Name == DbProviderManifest.CollationFacetName);

            }
            else 
            {
                return (facet.Name == EdmProviderManifest.StoreGeneratedPatternFacetName || 
                        facet.Name == DbProviderManifest.CollationFacetName); 
            }
        } 

        private IEnumerable GetAssociatedFacetDescriptions(EdmType type)
        {
            MethodInfo mi = typeof(EdmType).GetMethod("GetAssociatedFacetDescriptions", BindingFlags.NonPublic | BindingFlags.Instance); 
            Debug.Assert(mi != null, "Method GetAssociatedFacetDescriptions is missing");
            return (IEnumerable)mi.Invoke(type, new object[0]); 
        } 

        private string GetAttributeValueString(object o) 
        {
            if (o.GetType() == typeof(bool))
            {
                return o.ToString().ToLower(CultureInfo.InvariantCulture); 
            }
            else 
            { 
                return o.ToString();
            } 
        }

        private EdmType GetEdmType(TypeUsage typeUsage)
        { 
            if (_isModel)
            { 
                return GetModelType(typeUsage.EdmType); 
            }
            else 
            {
                return typeUsage.EdmType;
            }
        } 
        private string GetTypeName(TypeUsage typeUsage)
        { 
            EdmType type = GetEdmType(typeUsage); 
            if (type.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType)
            { 
                return type.Name;
            }
            else
            { 
                return GetFullName(type);
            } 
        } 

        private EdmType GetModelType(EdmType edmType) 
        {
            if (edmType.BuiltInTypeKind != BuiltInTypeKind.PrimitiveType)
            {
                return edmType; 
            }
 
            while (edmType != null && edmType.NamespaceName != EdmNamespace) 
            {
                edmType = edmType.BaseType; 
            }

            return edmType;
        } 

        private void WriteSchemaElement(string schemaNamespace, string provider, string providerManifestToken, params KeyValuePair[] xmlPrefixToNamespaces) 
        { 
            string xmlNamespace;
            if(_isModel) 
            {
                xmlNamespace = XmlConstants.ModelNamespace;
            }
            else 
            {
                xmlNamespace = XmlConstants.TargetNamespace; 
            } 
            _writer.WriteStartElement(XmlConstants.Schema, xmlNamespace);
            _writer.WriteAttributeString(XmlConstants.Namespace, schemaNamespace); 
            _writer.WriteAttributeString(XmlConstants.Alias, "Self");
            if (!_isModel)
            {
                if (!string.IsNullOrEmpty(provider)) 
                {
                    _writer.WriteAttributeString(XmlConstants.Provider, provider); 
                } 

                if (!string.IsNullOrEmpty(providerManifestToken)) 
                {
                    _writer.WriteAttributeString(XmlConstants.ProviderManifestToken, providerManifestToken);
                }
            } 

            // write out the extra xml namespaces and their pretty prefix 
            foreach (KeyValuePair xmlPrefixToNamespace in xmlPrefixToNamespaces) 
            {
                // see http://www.w3.org/TR/2006/REC-xml-names-20060816/ 
                _writer.WriteAttributeString("xmlns", xmlPrefixToNamespace.Key, null, xmlPrefixToNamespace.Value);
            }
        }
 
        private void WriteEntityContainerElement(EntityContainer container)
        { 
            _writer.WriteStartElement(XmlConstants.EntityContainer); 
            _writer.WriteAttributeString(XmlConstants.Name, container.Name);
            foreach (EntitySetBase set in container.BaseEntitySets) 
            {
                switch (set.BuiltInTypeKind)
                {
                    case BuiltInTypeKind.EntitySet: 
                        WriteEntitySetElement((EntitySet)set);
                        break; 
                    case BuiltInTypeKind.AssociationSet: 
                        WriteAssociationSetElement((AssociationSet)set);
                        break; 
                    default:
                        throw EDesignUtil.NonSerializableType(set.BuiltInTypeKind);
                }
            } 

 
            _writer.WriteEndElement(); 
        }
 
        private void WriteAssociationSetElement(AssociationSet associationSet)
        {
            _writer.WriteStartElement(XmlConstants.AssociationSet);
            _writer.WriteAttributeString(XmlConstants.Name, associationSet.Name); 
            _writer.WriteAttributeString(XmlConstants.Association, GetFullName(associationSet.ElementType));
 
            foreach (AssociationSetEnd end in associationSet.AssociationSetEnds) 
            {
                WriteAssociationSetEndElement(end); 
            }
            _writer.WriteEndElement();
        }
 
        private void WriteAssociationSetEndElement(AssociationSetEnd end)
        { 
            _writer.WriteStartElement(XmlConstants.End); 
            _writer.WriteAttributeString(XmlConstants.Role, end.Name);
            _writer.WriteAttributeString(XmlConstants.EntitySet, end.EntitySet.Name); 
            _writer.WriteEndElement();
        }

        private void WriteEntitySetElement(EntitySet entitySet) 
        {
            _writer.WriteStartElement(XmlConstants.EntitySet); 
            _writer.WriteAttributeString(XmlConstants.Name, entitySet.Name); 
            _writer.WriteAttributeString(XmlConstants.EntityType, GetFullName(entitySet.ElementType));
            WriteExtendedPropertyAttributes(entitySet); 

            MetadataProperty property;
            if (entitySet.MetadataProperties.TryGetValue(XmlConstants.DefiningQuery, false, out property) &&
                property.Value != null) 
            {
                _writer.WriteStartElement(XmlConstants.DefiningQuery); 
                _writer.WriteString(entitySet.DefiningQuery); 
                _writer.WriteEndElement();
            } 
            else
            {
                if (entitySet.MetadataProperties.TryGetValue(XmlConstants.Schema, false, out property) &&
                    property.Value != null) 
                {
                    _writer.WriteAttributeString(property.Name, property.Value.ToString()); 
                } 

                if (entitySet.MetadataProperties.TryGetValue(XmlConstants.Table, false, out property) && 
                    property.Value != null)
                {
                    _writer.WriteAttributeString(property.Name, property.Value.ToString());
                } 
            }
 
 
            _writer.WriteEndElement();
        } 

        private void WriteExtendedPropertyAttributes(MetadataItem item)
        {
            foreach (MetadataProperty property in item.MetadataProperties.Where(p => p.PropertyKind == PropertyKind.Extended)) 
            {
                string xmlNamespace, attributeName; 
                if (System.Data.EntityModel.SchemaObjectModel.SchemaElement.TrySplitExtendedMetadataPropertyName(property.Name, out xmlNamespace, out attributeName)) 
                {
                    _writer.WriteAttributeString(attributeName, xmlNamespace, property.Value.ToString()); 
                }
            }
        }
 
        private string GetFullName(EdmType type)
        { 
            string namespaceName = null; 
            string name;
            string modifierFormat = null; 

            if (type.BuiltInTypeKind == BuiltInTypeKind.CollectionType)
            {
                type = ((CollectionType)type).TypeUsage.EdmType; 
                modifierFormat = "Collection({0})";
            } 
 
            if (type.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType)
            { 
                // primitive types are not required to be qualified
                name = type.Name;
            }
            else 
            {
                namespaceName = type.NamespaceName; 
                name = type.Name; 
            }
 
            string qualifiedTypeName;
            if (namespaceName == null)
            {
                qualifiedTypeName = name; 
            }
            else 
            { 
                qualifiedTypeName = namespaceName + "." + name;
            } 

            if (modifierFormat != null)
            {
                qualifiedTypeName = string.Format(CultureInfo.InvariantCulture, modifierFormat, qualifiedTypeName); 
            }
 
            return qualifiedTypeName; 
         }
 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 
using System;
using System.Data.Common; 
using System.Collections.Generic;
using System.Text;
using System.Data.Metadata.Edm;
using System.Reflection; 
using System.Diagnostics;
using System.Xml; 
using System.Globalization; 
using System.IO;
using System.Data.Entity.Design.SsdlGenerator; 
using System.Linq;

namespace System.Data.Entity.Design.Common
{ 
    /// 
    /// This class is reponsible for serailizing Edm Metadata out to the appropriate file .csdl or .ssdl 
    ///  
    internal class MetadataItemSerializer
    { 
        public static readonly EdmType NoSpecificTypeSentinal = MetadataItem.GetBuiltInType(BuiltInTypeKind.EdmType);

        private bool _isModel;
        private ErrorsLookup _errorsLookup; 
        private XmlWriter _writer;
        private MetadataItemSerializer(XmlWriter writer, bool isModel, ErrorsLookup errorsLookup) 
        { 
            _writer = writer;
            _isModel = isModel; 
            _errorsLookup = errorsLookup;
        }

        public class ErrorsLookup : Dictionary> { } 

        internal readonly string EdmNamespace = "Edm"; 
 
        public static void WriteXml(XmlWriter writer, ItemCollection collection, string namespaceToWrite, params KeyValuePair [] xmlPrefixToNamespaces)
        { 
            WriteXml(writer, collection, namespaceToWrite, new ErrorsLookup(), new List(), null, null, xmlPrefixToNamespaces);
        }

        internal static void WriteXml(XmlWriter writer, ItemCollection collection, string namespaceToWrite, ErrorsLookup errorsLookup, List commentedOutItems, string provider, string providerManifestToken, params KeyValuePair[] xmlPrefixToNamespaces) 
        {
            Debug.Assert(writer != null, "writer parameter is null"); 
            Debug.Assert(collection != null, "collection parameter is null"); 
            Debug.Assert(errorsLookup != null, "errorsLookup parameter is null");
            Debug.Assert(!string.IsNullOrEmpty(namespaceToWrite), "namespaceToWrite parameter is null or empty"); 

            MetadataItemSerializer serializer = new MetadataItemSerializer(writer, collection.DataSpace == DataSpace.CSpace, errorsLookup);

            serializer.ValidateNamespace(namespaceToWrite); 
            serializer.WriteSchemaElement(namespaceToWrite, provider, providerManifestToken, xmlPrefixToNamespaces);
            serializer.WriteErrorsComment(NoSpecificTypeSentinal); 
            foreach (EntityContainer item in collection.GetItems()) 
            {
                serializer.WriteEntityContainerElement(item); 
            }

            foreach (EdmType type in collection.GetItems())
            { 
                // is it in the right space (c or s)
                // does it have the right namespace? 
                if (type.NamespaceName == namespaceToWrite) 
                {
                    serializer.WriteTypeElement(type); 
                }
            }

            if(commentedOutItems.Count > 0) 
            {
                StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture); 
                XmlWriterSettings settings = new XmlWriterSettings(); 
                settings.Indent = true;
                settings.OmitXmlDeclaration = true; 
                // we can have more than one commented out type
                // which will look like multiple root elements, so this is a fragment
                settings.ConformanceLevel = ConformanceLevel.Fragment;
                XmlWriter commentWriter = XmlWriter.Create(stringWriter, settings); 
                MetadataItemSerializer commmentSerializer = new MetadataItemSerializer(commentWriter, collection.DataSpace == DataSpace.CSpace, errorsLookup);
                foreach (EdmType type in commentedOutItems) 
                { 
                    commmentSerializer.WriteTypeElement(type);
                } 
                commentWriter.Flush();
                //This is not the cleanest thing to do but XmlTextWriter
                //does not allow writing xml comment characters while writing a comment.
                //and since we know exactly the string we write, this is pretty safe. 
                string comment = RemoveXmlCommentCharacters(stringWriter);
                writer.WriteComment(comment); 
            } 
            writer.WriteEndElement();
        } 

        private static string RemoveXmlCommentCharacters(StringWriter stringWriter)
        {
            string comment = stringWriter.GetStringBuilder().ToString(); 
            while (comment.Contains(XmlConstants.XmlCommentStartString))
            { 
                comment = comment.Replace(XmlConstants.XmlCommentStartString, String.Empty); 
            }
            while (comment.Contains(XmlConstants.XmlCommentEndString)) 
            {
                comment = comment.Replace(XmlConstants.XmlCommentEndString, String.Empty);
            }
            return comment; 
        }
 
        private void ValidateNamespace(string namespaceToWrite) 
        {
            if (EdmItemCollection.IsSystemNamespace(MetadataItem.EdmProviderManifest, namespaceToWrite)) 
            {
                throw EDesignUtil.EdmReservedNamespace(namespaceToWrite);
            }
        } 

        private void WriteTypeElement(EdmType type) 
        { 
            WriteErrorsComment(type);
            switch (type.BuiltInTypeKind) 
            {
                case BuiltInTypeKind.EntityType:
                    WriteEntityTypeElement((EntityType)type);
                    break; 
                case BuiltInTypeKind.AssociationType:
                    WriteAssociationTypeElement((AssociationType)type); 
                    break; 
                case BuiltInTypeKind.EdmFunction:
                    Debug.Assert(!_isModel, "we only expect functions in sspace"); 
                    WriteFunctionElement((EdmFunction)type);
                    break;
                case BuiltInTypeKind.ComplexType:
                    WriteComplexTypeElement((ComplexType)type); 
                    break;
                default: 
                    throw EDesignUtil.NonSerializableType(type.BuiltInTypeKind); 
            }
        } 

        private void WriteFunctionElement(EdmFunction function)
        {
            _writer.WriteStartElement(XmlConstants.Function); 
            _writer.WriteAttributeString(XmlConstants.Name, function.Name);
            if (function.ReturnParameter != null) 
            { 
                _writer.WriteAttributeString(XmlConstants.ReturnType, GetFullName(function.ReturnParameter.TypeUsage.EdmType));
            } 
            _writer.WriteAttributeString(XmlConstants.AggregateAttribute, GetAttributeValueString(function.AggregateAttribute));
            _writer.WriteAttributeString(XmlConstants.BuiltInAttribute, GetAttributeValueString(function.BuiltInAttribute));
            _writer.WriteAttributeString(XmlConstants.NiladicFunction, GetAttributeValueString(function.NiladicFunctionAttribute));
            _writer.WriteAttributeString(XmlConstants.IsComposable, GetAttributeValueString(function.IsComposableAttribute)); 
            _writer.WriteAttributeString(XmlConstants.ParameterTypeSemantics, GetAttributeValueString(function.ParameterTypeSemanticsAttribute));
 
            if (function.StoreFunctionNameAttribute != null) 
            {
                _writer.WriteAttributeString(XmlConstants.StoreFunctionName, function.StoreFunctionNameAttribute); 
            }

            if(function.CommandTextAttribute != null)
            { 
                _writer.WriteAttributeString(XmlConstants.CommandText, function.CommandTextAttribute);
            } 
 
            if (function.Schema != null)
            { 
                _writer.WriteAttributeString(XmlConstants.Schema, function.Schema);
            }

            foreach (FunctionParameter parameter in function.Parameters) 
            {
                WriteFunctionParameterElement(parameter); 
            } 

            _writer.WriteEndElement(); 
        }

        private void WriteFunctionParameterElement(FunctionParameter parameter)
        { 
            _writer.WriteStartElement(XmlConstants.Parameter);
            _writer.WriteAttributeString(XmlConstants.Name, parameter.Name); 
            _writer.WriteAttributeString(XmlConstants.TypeAttribute, GetFullName(parameter.TypeUsage.EdmType)); 
            _writer.WriteAttributeString(XmlConstants.Mode, GetAttributeValueString(parameter.Mode));
            _writer.WriteEndElement(); 
        }


        private void WriteComplexTypeElement(ComplexType complexType) 
        {
            _writer.WriteStartElement(XmlConstants.ComplexType); 
            _writer.WriteAttributeString(XmlConstants.Name, complexType.Name); 
            if (complexType.BaseType != null)
            { 
                _writer.WriteAttributeString(XmlConstants.BaseType, GetFullName(complexType.BaseType));
            }

            foreach (EdmMember member in complexType.GetDeclaredOnlyMembers()) 
            {
                WritePropertyElement(member); 
            } 
            _writer.WriteEndElement();
        } 

        private void WriteAssociationTypeElement(AssociationType associationType)
        {
            _writer.WriteStartElement(XmlConstants.Association); 
            _writer.WriteAttributeString(XmlConstants.Name, associationType.Name);
            foreach (RelationshipEndMember end in associationType.RelationshipEndMembers) 
            { 
                WriteRelationshipEndElement(end);
            } 

            foreach (ReferentialConstraint constraint in associationType.ReferentialConstraints)
            {
                WriteReferentialConstraintElement(constraint); 
            }
 
            _writer.WriteEndElement(); 
        }
 
        private void WriteReferentialConstraintElement(ReferentialConstraint constraint)
        {
            _writer.WriteStartElement(XmlConstants.ReferentialConstraint);
            WriteReferentialConstraintRoleElement(XmlConstants.PrincipalRole, constraint.FromRole, constraint.FromProperties); 
            WriteReferentialConstraintRoleElement(XmlConstants.DependentRole, constraint.ToRole, constraint.ToProperties);
            _writer.WriteEndElement(); 
        } 

        private void WriteReferentialConstraintRoleElement(string nodeName, RelationshipEndMember end, IList properties) 
        {
            // Generate the principal and dependent role nodes
            _writer.WriteStartElement(nodeName);
            _writer.WriteAttributeString(XmlConstants.Role, end.Name); 
            for (int i = 0; i < properties.Count; i++)
            { 
                _writer.WriteStartElement(XmlConstants.PropertyRef); 
                _writer.WriteAttributeString(XmlConstants.Name, properties[i].Name);
                _writer.WriteEndElement(); 
            }
            _writer.WriteEndElement();
        }
 
        private void WriteRelationshipEndElement(RelationshipEndMember end)
        { 
            _writer.WriteStartElement(XmlConstants.End); 
            _writer.WriteAttributeString(XmlConstants.Role, end.Name);
 
            string typeName = GetFullName(((RefType)end.TypeUsage.EdmType).ElementType);
            _writer.WriteAttributeString(XmlConstants.TypeAttribute, typeName);
            _writer.WriteAttributeString(XmlConstants.Multiplicity, GetXmlMultiplicity(end.RelationshipMultiplicity));
            if (end.DeleteBehavior != OperationAction.None) 
            {
                WriteOperationActionElement(XmlConstants.OnDelete, end.DeleteBehavior); 
            } 
            _writer.WriteEndElement();
        } 

        private void WriteOperationActionElement(string elementName, OperationAction operationAction)
        {
            _writer.WriteStartElement(elementName); 
            _writer.WriteAttributeString(XmlConstants.Action, operationAction.ToString());
            _writer.WriteEndElement(); 
        } 

        private string GetXmlMultiplicity(RelationshipMultiplicity relationshipMultiplicity) 
        {
            switch(relationshipMultiplicity)
            {
                case RelationshipMultiplicity.Many: 
                    return "*";
                case RelationshipMultiplicity.One: 
                    return "1"; 
                case RelationshipMultiplicity.ZeroOrOne:
                    return "0..1"; 
                default:
                    Debug.Fail("Did you add a new RelationshipMultiplicity?");
                    return string.Empty;
            } 
        }
 
        private void WriteEntityTypeElement(EntityType entityType) 
        {
            _writer.WriteStartElement(XmlConstants.EntityType); 
            _writer.WriteAttributeString(XmlConstants.Name, entityType.Name);
            if (entityType.BaseType != null)
            {
                _writer.WriteAttributeString(XmlConstants.BaseType, GetFullName(entityType.BaseType)); 
            }
 
            if (entityType.Abstract) 
            {
                _writer.WriteAttributeString(XmlConstants.Abstract, XmlConstants.True); 
            }

            if (entityType.KeyMembers.Count != 0 &&
                entityType.KeyMembers[0].DeclaringType == entityType) // they are declared on this entity 
            {
                _writer.WriteStartElement(XmlConstants.Key); 
                for (int i = 0; i < entityType.KeyMembers.Count; i++) 
                {
                    _writer.WriteStartElement(XmlConstants.PropertyRef); 
                    _writer.WriteAttributeString(XmlConstants.Name, entityType.KeyMembers[i].Name);
                    _writer.WriteEndElement();
                }
                _writer.WriteEndElement(); 
            }
 
            foreach (EdmProperty member in entityType.GetDeclaredOnlyMembers()) 
            {
                WritePropertyElement(member); 
            }

            foreach (NavigationProperty navigationProperty in entityType.NavigationProperties )
            { 
                if (navigationProperty.DeclaringType == entityType)
                { 
                    WriteNavigationPropertyElement(navigationProperty); 
                }
            } 
            _writer.WriteEndElement();
        }

        private void WriteErrorsComment(EdmType type) 
        {
            List errors; 
            if (_errorsLookup.TryGetValue(type, out errors)) 
            {
                Debug.Assert(errors.Count > 0, "how did we get an empty errors collection?"); 

                StringBuilder builder = new StringBuilder();
                builder.AppendLine(Strings.MetadataItemErrorsFoundDuringGeneration);
                foreach (EdmSchemaError error in errors) 
                {
                    builder.AppendLine(error.ToString()); 
                } 
                _writer.WriteComment(builder.ToString());
            } 
        }

        private void WriteNavigationPropertyElement(NavigationProperty member)
        { 
            _writer.WriteStartElement(XmlConstants.NavigationProperty);
            _writer.WriteAttributeString(XmlConstants.Name, member.Name); 
            _writer.WriteAttributeString(XmlConstants.Relationship, member.RelationshipType.FullName); 
            _writer.WriteAttributeString(XmlConstants.FromRole, member.FromEndMember.Name);
            _writer.WriteAttributeString(XmlConstants.ToRole, member.ToEndMember.Name); 
            _writer.WriteEndElement();
        }

        private void WritePropertyElement(EdmMember member) 
        {
            _writer.WriteStartElement(XmlConstants.Property); 
            _writer.WriteAttributeString(XmlConstants.Name, member.Name); 
            _writer.WriteAttributeString(XmlConstants.TypeAttribute, GetTypeName(member.TypeUsage));
            WritePropertyTypeFacets(member.TypeUsage); 
            _writer.WriteEndElement();
        }

        private void WritePropertyTypeFacets(TypeUsage typeUsage) 
        {
            // we need to use the facets for this particular provider, not the ones that they type 
            // may have been converted to (think CSDL types converted to provider types) 
            EdmType type = GetEdmType(typeUsage);
            IEnumerable providerDescriptions = GetAssociatedFacetDescriptions(type); 

            foreach (Facet facet in typeUsage.Facets)
            {
                FacetDescription providerFacetDescription = null; 
                if (IsSpecialFacet(facet))
                { 
                    providerFacetDescription = facet.Description; 
                }
                else 
                {
                    foreach (FacetDescription description in providerDescriptions)
                    {
                        if (description.FacetName == facet.Name) 
                        {
                            providerFacetDescription = description; 
                            break; 
                        }
                    } 
                }

                //
                // Don't emit this facet if we shouldn't 
                //
                if (SkipFacet(facet, providerFacetDescription)) 
                { 
                    continue;
                } 

                //
                // Special case for MaxLength facet value of "Max"
                // 
                if (_isModel &&
                    type.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType) 
                { 
                    PrimitiveType primitiveType = (PrimitiveType)type;
 
                    if ((primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.String ||
                         primitiveType.PrimitiveTypeKind == PrimitiveTypeKind.Binary) &&
                        facet.Name == DbProviderManifest.MaxLengthFacetName &&
                        Helper.IsUnboundedFacetValue(facet)) 
                    {
                        _writer.WriteAttributeString(TranslateFacetNameToAttributeName(facet.Name), XmlConstants.Max); 
                        continue; 
                    }
                } 

                _writer.WriteAttributeString(TranslateFacetNameToAttributeName(facet.Name), GetAttributeValueString(facet.Value));
            }
        } 

 
        private string TranslateFacetNameToAttributeName(string facetName) 
        {
            if(DbProviderManifest.DefaultValueFacetName == facetName) 
            {
                return XmlConstants.DefaultValueAttribute;
            }
 
            return facetName;
        } 
 
        /// 
        /// Should this facet be skipped ? 
        /// A facet should be skipped if it satsifies one of the following
        ///   - the providerFacetDescription is null - (ie) the provider knows of no such facet
        ///   - the facetDescription indicates that the facet must have a constant value
        ///   - the facet value is null 
        ///   - the facet value is the default value for the facet, and the facet is not required
        ///   - we're emitting a model schema, and the facet in question is one of the following 
        ///       - MaxLength, FixedLength, Unicode, Collation, Precision, Scale, DateTimeKind 
        /// 
        /// the facet in question 
        /// facet description in the provider
        /// true, if the facet should be skipped
        private bool SkipFacet(Facet facet, FacetDescription providerFacetDescription)
        { 
            //
            // if the provider doesn't recognize it, it will complain 
            // when it sees it; so don't put it in 
            //
            if (providerFacetDescription == null) 
            {
                return true;
            }
            // skip it if it is constant for the current provider 
            if (providerFacetDescription.IsConstant)
            { 
                return true; 
            }
 
            //
            // Null facets can and should be omitted
            //
            if (facet.Value == null) 
            {
                return true; 
            } 

            // 
            // skip if it is not required, and has the default value
            //
            if (!providerFacetDescription.IsRequired &&
                facet.Value.Equals(providerFacetDescription.DefaultValue)) 
            {
                return true; 
            } 

            return false; 
        }

        private bool IsSpecialFacet(Facet facet)
        { 
            if(_isModel)
            { 
                return (facet.Name == "ClientAutoGenerated" || 
                        facet.Name == EdmProviderManifest.ConcurrencyModeFacetName ||
                        facet.Name == "StoreGenerated" || 
                        facet.Name == DbProviderManifest.CollationFacetName);

            }
            else 
            {
                return (facet.Name == EdmProviderManifest.StoreGeneratedPatternFacetName || 
                        facet.Name == DbProviderManifest.CollationFacetName); 
            }
        } 

        private IEnumerable GetAssociatedFacetDescriptions(EdmType type)
        {
            MethodInfo mi = typeof(EdmType).GetMethod("GetAssociatedFacetDescriptions", BindingFlags.NonPublic | BindingFlags.Instance); 
            Debug.Assert(mi != null, "Method GetAssociatedFacetDescriptions is missing");
            return (IEnumerable)mi.Invoke(type, new object[0]); 
        } 

        private string GetAttributeValueString(object o) 
        {
            if (o.GetType() == typeof(bool))
            {
                return o.ToString().ToLower(CultureInfo.InvariantCulture); 
            }
            else 
            { 
                return o.ToString();
            } 
        }

        private EdmType GetEdmType(TypeUsage typeUsage)
        { 
            if (_isModel)
            { 
                return GetModelType(typeUsage.EdmType); 
            }
            else 
            {
                return typeUsage.EdmType;
            }
        } 
        private string GetTypeName(TypeUsage typeUsage)
        { 
            EdmType type = GetEdmType(typeUsage); 
            if (type.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType)
            { 
                return type.Name;
            }
            else
            { 
                return GetFullName(type);
            } 
        } 

        private EdmType GetModelType(EdmType edmType) 
        {
            if (edmType.BuiltInTypeKind != BuiltInTypeKind.PrimitiveType)
            {
                return edmType; 
            }
 
            while (edmType != null && edmType.NamespaceName != EdmNamespace) 
            {
                edmType = edmType.BaseType; 
            }

            return edmType;
        } 

        private void WriteSchemaElement(string schemaNamespace, string provider, string providerManifestToken, params KeyValuePair[] xmlPrefixToNamespaces) 
        { 
            string xmlNamespace;
            if(_isModel) 
            {
                xmlNamespace = XmlConstants.ModelNamespace;
            }
            else 
            {
                xmlNamespace = XmlConstants.TargetNamespace; 
            } 
            _writer.WriteStartElement(XmlConstants.Schema, xmlNamespace);
            _writer.WriteAttributeString(XmlConstants.Namespace, schemaNamespace); 
            _writer.WriteAttributeString(XmlConstants.Alias, "Self");
            if (!_isModel)
            {
                if (!string.IsNullOrEmpty(provider)) 
                {
                    _writer.WriteAttributeString(XmlConstants.Provider, provider); 
                } 

                if (!string.IsNullOrEmpty(providerManifestToken)) 
                {
                    _writer.WriteAttributeString(XmlConstants.ProviderManifestToken, providerManifestToken);
                }
            } 

            // write out the extra xml namespaces and their pretty prefix 
            foreach (KeyValuePair xmlPrefixToNamespace in xmlPrefixToNamespaces) 
            {
                // see http://www.w3.org/TR/2006/REC-xml-names-20060816/ 
                _writer.WriteAttributeString("xmlns", xmlPrefixToNamespace.Key, null, xmlPrefixToNamespace.Value);
            }
        }
 
        private void WriteEntityContainerElement(EntityContainer container)
        { 
            _writer.WriteStartElement(XmlConstants.EntityContainer); 
            _writer.WriteAttributeString(XmlConstants.Name, container.Name);
            foreach (EntitySetBase set in container.BaseEntitySets) 
            {
                switch (set.BuiltInTypeKind)
                {
                    case BuiltInTypeKind.EntitySet: 
                        WriteEntitySetElement((EntitySet)set);
                        break; 
                    case BuiltInTypeKind.AssociationSet: 
                        WriteAssociationSetElement((AssociationSet)set);
                        break; 
                    default:
                        throw EDesignUtil.NonSerializableType(set.BuiltInTypeKind);
                }
            } 

 
            _writer.WriteEndElement(); 
        }
 
        private void WriteAssociationSetElement(AssociationSet associationSet)
        {
            _writer.WriteStartElement(XmlConstants.AssociationSet);
            _writer.WriteAttributeString(XmlConstants.Name, associationSet.Name); 
            _writer.WriteAttributeString(XmlConstants.Association, GetFullName(associationSet.ElementType));
 
            foreach (AssociationSetEnd end in associationSet.AssociationSetEnds) 
            {
                WriteAssociationSetEndElement(end); 
            }
            _writer.WriteEndElement();
        }
 
        private void WriteAssociationSetEndElement(AssociationSetEnd end)
        { 
            _writer.WriteStartElement(XmlConstants.End); 
            _writer.WriteAttributeString(XmlConstants.Role, end.Name);
            _writer.WriteAttributeString(XmlConstants.EntitySet, end.EntitySet.Name); 
            _writer.WriteEndElement();
        }

        private void WriteEntitySetElement(EntitySet entitySet) 
        {
            _writer.WriteStartElement(XmlConstants.EntitySet); 
            _writer.WriteAttributeString(XmlConstants.Name, entitySet.Name); 
            _writer.WriteAttributeString(XmlConstants.EntityType, GetFullName(entitySet.ElementType));
            WriteExtendedPropertyAttributes(entitySet); 

            MetadataProperty property;
            if (entitySet.MetadataProperties.TryGetValue(XmlConstants.DefiningQuery, false, out property) &&
                property.Value != null) 
            {
                _writer.WriteStartElement(XmlConstants.DefiningQuery); 
                _writer.WriteString(entitySet.DefiningQuery); 
                _writer.WriteEndElement();
            } 
            else
            {
                if (entitySet.MetadataProperties.TryGetValue(XmlConstants.Schema, false, out property) &&
                    property.Value != null) 
                {
                    _writer.WriteAttributeString(property.Name, property.Value.ToString()); 
                } 

                if (entitySet.MetadataProperties.TryGetValue(XmlConstants.Table, false, out property) && 
                    property.Value != null)
                {
                    _writer.WriteAttributeString(property.Name, property.Value.ToString());
                } 
            }
 
 
            _writer.WriteEndElement();
        } 

        private void WriteExtendedPropertyAttributes(MetadataItem item)
        {
            foreach (MetadataProperty property in item.MetadataProperties.Where(p => p.PropertyKind == PropertyKind.Extended)) 
            {
                string xmlNamespace, attributeName; 
                if (System.Data.EntityModel.SchemaObjectModel.SchemaElement.TrySplitExtendedMetadataPropertyName(property.Name, out xmlNamespace, out attributeName)) 
                {
                    _writer.WriteAttributeString(attributeName, xmlNamespace, property.Value.ToString()); 
                }
            }
        }
 
        private string GetFullName(EdmType type)
        { 
            string namespaceName = null; 
            string name;
            string modifierFormat = null; 

            if (type.BuiltInTypeKind == BuiltInTypeKind.CollectionType)
            {
                type = ((CollectionType)type).TypeUsage.EdmType; 
                modifierFormat = "Collection({0})";
            } 
 
            if (type.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType)
            { 
                // primitive types are not required to be qualified
                name = type.Name;
            }
            else 
            {
                namespaceName = type.NamespaceName; 
                name = type.Name; 
            }
 
            string qualifiedTypeName;
            if (namespaceName == null)
            {
                qualifiedTypeName = name; 
            }
            else 
            { 
                qualifiedTypeName = namespaceName + "." + name;
            } 

            if (modifierFormat != null)
            {
                qualifiedTypeName = string.Format(CultureInfo.InvariantCulture, modifierFormat, qualifiedTypeName); 
            }
 
            return qualifiedTypeName; 
         }
 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK