/// <summary> /// Write the metadata of all the properties for the given typein the xmlWriter /// </summary> /// <param name="xmlWriter">xmlWriter in which metadata needs to be written</param> /// <param name="type">resource type whose property metadata needs to be written</param> /// <param name="associationsInThisNamespace">list of associations in the current namespace.</param> /// <param name="metadataManager">metadata manager instance</param> private static void WriteProperties( XmlWriter xmlWriter, ResourceType type, Dictionary<string, ResourceAssociationType> associationsInThisNamespace, MetadataManager metadataManager) { Debug.Assert(xmlWriter != null, "xmlWriter != null"); Debug.Assert(type != null, "type != null"); foreach (ResourceProperty resourceProperty in metadataManager.GetPropertiesDeclaredInThisType(type)) { string elementName; // For primitive types, get the corresponding edm typename if (resourceProperty.TypeKind == ResourceTypeKind.Primitive) { xmlWriter.WriteStartElement(XmlConstants.Property); xmlWriter.WriteAttributeString(XmlConstants.Name, resourceProperty.Name); xmlWriter.WriteAttributeString(XmlConstants.Type, resourceProperty.ResourceType.FullName); WritePrimitivePropertyFacets(xmlWriter, resourceProperty); if (!String.IsNullOrEmpty(resourceProperty.MimeType)) { MetadataSerializer.WriteDataWebMetadata(xmlWriter, XmlConstants.DataWebMimeTypeAttributeName, resourceProperty.MimeType); } if (type.ResourceTypeKind == ResourceTypeKind.EntityType && type.ETagProperties.Contains(resourceProperty)) { xmlWriter.WriteAttributeString(XmlConstants.ConcurrencyAttribute, XmlConstants.ConcurrencyFixedValue); } if (type.HasEntityPropertyMappings) { var currentEpmInfos = type.OwnEpmInfo.Where(e => e.SourcePath.Split('/').First() == resourceProperty.Name); WriteEpmProperties(xmlWriter, currentEpmInfos, true, false); } } else if (resourceProperty.Kind == ResourcePropertyKind.ComplexType) { xmlWriter.WriteStartElement(XmlConstants.Property); xmlWriter.WriteAttributeString(XmlConstants.Name, resourceProperty.Name); elementName = resourceProperty.ResourceType.FullName; xmlWriter.WriteAttributeString(XmlConstants.Type, elementName); // Edm doesn't support nullable complex type properties xmlWriter.WriteAttributeString(XmlConstants.Nullable, XmlConstants.XmlFalseLiteral); if (type.HasEntityPropertyMappings) { var currentEpmInfos = type.OwnEpmInfo.Where(e => e.SourcePath.Split('/').First() == resourceProperty.Name); WriteEpmProperties(xmlWriter, currentEpmInfos, currentEpmInfos.Any(ei => ei.SourcePath == resourceProperty.Name), true); } } else { Debug.Assert( ResourceTypeKind.EntityType == resourceProperty.TypeKind, "Unexpected property type kind"); xmlWriter.WriteStartElement(XmlConstants.NavigationProperty); xmlWriter.WriteAttributeString(XmlConstants.Name, resourceProperty.Name); elementName = resourceProperty.ResourceType.FullName; string associationTypeLookupName = MetadataManager.GetAssociationTypeLookupName(type, resourceProperty); ResourceAssociationType associationType; if (!associationsInThisNamespace.TryGetValue(associationTypeLookupName, out associationType)) { throw new InvalidOperationException(Strings.MetadataSerializer_NoResourceAssociationSetForNavigationProperty(resourceProperty.Name, type.FullName)); } ResourceAssociationTypeEnd thisEnd = associationType.GetResourceAssociationTypeEnd(type, resourceProperty); ResourceAssociationTypeEnd relatedEnd = associationType.GetRelatedResourceAssociationSetEnd(type, resourceProperty); xmlWriter.WriteAttributeString(XmlConstants.Relationship, associationType.FullName); xmlWriter.WriteAttributeString(XmlConstants.FromRole, thisEnd.Name); xmlWriter.WriteAttributeString(XmlConstants.ToRole, relatedEnd.Name); } xmlWriter.WriteEndElement(); } }