1 //---------------------------------------------------------------------
2 // <copyright file="EntityDesignerUtils.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
8 //---------------------------------------------------------------------
13 using System.Data.Metadata.Edm;
14 using System.Data.Mapping;
16 namespace System.Data.Entity.Design
18 internal static class EntityDesignerUtils
20 internal const string EdmxRootElementName = "Edmx";
21 internal const string EdmxNamespaceUriV1 = "http://schemas.microsoft.com/ado/2007/06/edmx";
22 internal const string EdmxNamespaceUriV2 = "http://schemas.microsoft.com/ado/2008/10/edmx";
23 internal const string EdmxNamespaceUriV3 = "http://schemas.microsoft.com/ado/2009/11/edmx";
25 private static readonly EFNamespaceSet v1Namespaces = new EFNamespaceSet
27 Edmx = EdmxNamespaceUriV1,
28 Csdl = XmlConstants.ModelNamespace_1,
29 Msl = StorageMslConstructs.NamespaceUriV1,
30 Ssdl = XmlConstants.TargetNamespace_1,
32 private static readonly EFNamespaceSet v2Namespaces = new EFNamespaceSet
34 Edmx = EdmxNamespaceUriV2,
35 Csdl = XmlConstants.ModelNamespace_2,
36 Msl = StorageMslConstructs.NamespaceUriV2,
37 Ssdl = XmlConstants.TargetNamespace_2,
39 private static readonly EFNamespaceSet v3Namespaces = new EFNamespaceSet
41 Edmx = EdmxNamespaceUriV3,
42 Csdl = XmlConstants.ModelNamespace_3,
43 Msl = StorageMslConstructs.NamespaceUriV3,
44 Ssdl = XmlConstants.TargetNamespace_3,
46 internal static readonly string _edmxFileExtension = ".edmx";
49 /// Extract the Conceptual, Mapping and Storage nodes from an EDMX input streams, and extract the value of the metadataArtifactProcessing property.
51 /// <param name="edmxInputStream"></param>
52 /// <param name="conceptualSchemaNode"></param>
53 /// <param name="mappingNode"></param>
54 /// <param name="storageSchemaNode"></param>
56 internal static void ExtractConceptualMappingAndStorageNodes(StreamReader edmxInputStream,
57 out XmlElement conceptualSchemaNode, out XmlElement mappingNode, out XmlElement storageSchemaNode, out string metadataArtifactProcessingValue)
59 // load up an XML document representing the edmx file
60 XmlDocument xmlDocument = new XmlDocument();
61 using (var reader = XmlReader.Create(edmxInputStream))
63 xmlDocument.Load(reader);
66 EFNamespaceSet set = v3Namespaces;
67 if (xmlDocument.DocumentElement.NamespaceURI == v2Namespaces.Edmx)
71 else if (xmlDocument.DocumentElement.NamespaceURI == v1Namespaces.Edmx)
76 XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmlDocument.NameTable);
77 nsMgr.AddNamespace("edmx", set.Edmx);
78 nsMgr.AddNamespace("edm", set.Csdl);
79 nsMgr.AddNamespace("ssdl", set.Ssdl);
80 nsMgr.AddNamespace("map", set.Msl);
82 // find the ConceptualModel Schema node
83 conceptualSchemaNode = (XmlElement)xmlDocument.SelectSingleNode(
84 "/edmx:Edmx/edmx:Runtime/edmx:ConceptualModels/edm:Schema", nsMgr);
86 // find the StorageModel Schema node
87 storageSchemaNode = (XmlElement)xmlDocument.SelectSingleNode(
88 "/edmx:Edmx/edmx:Runtime/edmx:StorageModels/ssdl:Schema", nsMgr);
90 // find the Mapping node
91 mappingNode = (XmlElement)xmlDocument.SelectSingleNode(
92 "/edmx:Edmx/edmx:Runtime/edmx:Mappings/map:Mapping", nsMgr);
94 // find the Connection node
96 metadataArtifactProcessingValue = String.Empty;
97 XmlNodeList connectionProperties = xmlDocument.SelectNodes(
98 "/edmx:Edmx/edmx:Designer/edmx:Connection/edmx:DesignerInfoPropertySet/edmx:DesignerProperty", nsMgr);
99 if (connectionProperties != null)
101 foreach (XmlNode propertyNode in connectionProperties)
103 foreach (XmlAttribute a in propertyNode.Attributes)
105 // treat attribute names case-sensitive (since it is xml), but attribute value case-insensitive to be accommodating .
106 if (a.Name.Equals("Name", StringComparison.Ordinal) && a.Value.Equals("MetadataArtifactProcessing", StringComparison.OrdinalIgnoreCase))
108 foreach (XmlAttribute a2 in propertyNode.Attributes)
110 if (a2.Name.Equals("Value", StringComparison.Ordinal))
112 metadataArtifactProcessingValue = a2.Value;
122 // utility method to ensure an XmlElement (containing the C, M or S element
123 // from the Edmx file) is sent out to a stream in the same format
124 internal static void OutputXmlElementToStream(XmlElement xmlElement, Stream stream)
126 XmlWriterSettings settings = new XmlWriterSettings();
127 settings.Encoding = Encoding.UTF8;
128 settings.Indent = true;
130 // set up output document
131 XmlDocument outputXmlDoc = new XmlDocument();
132 XmlNode importedElement = outputXmlDoc.ImportNode(xmlElement, true);
133 outputXmlDoc.AppendChild(importedElement);
135 // write out XmlDocument
136 XmlWriter writer = null;
139 writer = XmlWriter.Create(stream, settings);
140 outputXmlDoc.WriteTo(writer);
144 if (writer != null) { writer.Close(); }
148 private struct EFNamespaceSet