Esempio n. 1
0
        public static CSDLContainer IntegrateMSLInCSDLContainer(CSDLContainer csdlContainer, SSDLContainer ssdlContainer, XElement edmxRuntime)
        {
            XElement mappingsElement = edmxRuntime.Element(XName.Get("Mappings", edmxNamespace.NamespaceName));
            
            if (mappingsElement == null || mappingsElement.IsEmpty)
            	return null;
            
            XElement mappingElement = mappingsElement.Element(XName.Get("Mapping", mslNamespace.NamespaceName));
            
            if (mappingElement == null || mappingElement.IsEmpty)
            	return null;

            XElement entityContainerMappingElement = mappingElement.Element(XName.Get("EntityContainerMapping", mslNamespace.NamespaceName));
            
            if (entityContainerMappingElement == null || entityContainerMappingElement.IsEmpty)
            	return null;
            
            #region EntityTypes
            
            foreach (var entityTypeMappingElement in entityContainerMappingElement.Elements(XName.Get("EntitySetMapping", mslNamespace.NamespaceName)).SelectMany(entitySetElement => entitySetElement.Elements(XName.Get("EntityTypeMapping", mslNamespace.NamespaceName))))
            {
                var typeName = entityTypeMappingElement.Attribute("TypeName").Value;
                if (typeName.IndexOf("(") != -1)
                    typeName = typeName.Remove(typeName.IndexOf(")")).Substring(typeName.IndexOf("(") + 1);
                var entityType = csdlContainer.EntityTypes.GetByName(GetName(typeName));
                entityType.Mapping.BeginInit();
                var mapping = entityType.Mapping;
                foreach (var mappingFragmentElement in entityTypeMappingElement.Elements(XName.Get("MappingFragment", mslNamespace.NamespaceName)))
                {
                    var table = ssdlContainer.EntityTypes.GetByName(mappingFragmentElement.Attribute("StoreEntitySet").Value);
                    foreach (var scalarPropertyElement in mappingFragmentElement.Elements(XName.Get("ScalarProperty", mslNamespace.NamespaceName)))
                    {
                        var scalarProperty = entityType.AllScalarProperties.GetByName(scalarPropertyElement.Attribute("Name").Value);
                        var column = table.Properties.GetByName(scalarPropertyElement.Attribute("ColumnName").Value);
                        entityType.Mapping[scalarProperty, table] = column;
                    }

                    MapComplexProperties(mappingFragmentElement, mapping, entityType, table);

                    #region Conditions
                    
                    foreach (var conditionElement in mappingFragmentElement.Elements(XName.Get("Condition", mslNamespace.NamespaceName)))
                    {
                        var columnNameAttribute = conditionElement.Attribute("ColumnName");
                        ConditionMapping condition;
                        if (columnNameAttribute == null)
                            condition = new PropertyConditionMapping { CSDLProperty = entityType.ScalarProperties.GetByName(conditionElement.Attribute("Name").Value), Table = table };
                        else
                            condition = new ColumnConditionMapping { Column = table.Properties.GetByName(columnNameAttribute.Value) };
                        var valueAttribute = conditionElement.Attribute("Value");
                        if (valueAttribute == null)
                        {
                            if (conditionElement.Attribute("IsNull").Value == "false")
                                condition.Operator = ConditionOperator.IsNotNull;
                            else
                                condition.Operator = ConditionOperator.IsNull;
                        }
                        else
                        {
                            condition.Operator = ConditionOperator.Equals;
                            condition.Value = valueAttribute.Value;
                        }
                        mapping.ConditionsMapping.Add(condition);
                    }
                    
                    #endregion Conditions
                }
                mapping.Init = true;
                #region CUD Functions
                var modificationFunctionMappingElement = entityTypeMappingElement.Element(XName.Get("ModificationFunctionMapping", mslNamespace.NamespaceName));
                if (modificationFunctionMappingElement != null)
                {
                    var insertFunctionMappingElement = modificationFunctionMappingElement.Element(XName.Get("InsertFunction", mslNamespace.NamespaceName));
                    if (insertFunctionMappingElement != null)
                        mapping.InsertFunctionMapping = SetCUDFunctionMapping(ssdlContainer, entityType, insertFunctionMappingElement);
                    var updateFunctionMappingElement = modificationFunctionMappingElement.Element(XName.Get("UpdateFunction", mslNamespace.NamespaceName));
                    if (updateFunctionMappingElement != null)
                        mapping.UpdateFunctionMapping = SetCUDFunctionMapping(ssdlContainer, entityType, updateFunctionMappingElement);
                    var deleteFunctionMappingElement = modificationFunctionMappingElement.Element(XName.Get("DeleteFunction", mslNamespace.NamespaceName));
                    if (deleteFunctionMappingElement != null)
                        mapping.DeleteFunctionMapping = SetCUDFunctionMapping(ssdlContainer, entityType, deleteFunctionMappingElement);
                }
                #endregion CUD Functions

                entityType.Mapping.EndInit();
            }
            #endregion EntityTypes

            #region Associations
            foreach (var associationSetMappingElement in entityContainerMappingElement.Elements(XName.Get("AssociationSetMapping", mslNamespace.NamespaceName)))
            {
                var csdlAssociation = csdlContainer.AssociationsCreated.GetByName(GetName(associationSetMappingElement.Attribute("TypeName").Value));
                csdlAssociation.Mapping.BeginInit();
                var table = ssdlContainer.EntityTypes.GetByName(associationSetMappingElement.Attribute("StoreEntitySet").Value);
                foreach (var endPropertyElement in associationSetMappingElement.Elements(XName.Get("EndProperty", mslNamespace.NamespaceName)))
                {
                    NavigationProperty navigationProperty;
                    if (csdlAssociation.PropertyEnd1Role == endPropertyElement.Attribute("Name").Value)
                        navigationProperty = csdlAssociation.PropertyEnd1;
                    else
                        navigationProperty = csdlAssociation.PropertyEnd2;
                    var navigationPropertyMapping = navigationProperty.Mapping;
                    foreach (var scalarPropertyElement in endPropertyElement.Elements(XName.Get("ScalarProperty", mslNamespace.NamespaceName)))
                    {
                        var scalarProperty = navigationProperty.EntityType.AllScalarProperties.GetByName(scalarPropertyElement.Attribute("Name").Value);
                        var column = table.Properties.GetByName(scalarPropertyElement.Attribute("ColumnName").Value);
                        navigationPropertyMapping[scalarProperty] = column;
                    }
                }
                foreach (var conditionElement in associationSetMappingElement.Elements(XName.Get("Condition", mslNamespace.NamespaceName)))
                {
                    var columnNameAttribute = conditionElement.Attribute("ColumnName");
                    ColumnConditionMapping condition = new ColumnConditionMapping { Column = table.Properties.GetByName(columnNameAttribute.Value) }; ;
                    var valueAttribute = conditionElement.Attribute("Value");
                    if (valueAttribute == null)
                    {
                        if (conditionElement.Attribute("IsNull").Value == "false")
                            condition.Operator = ConditionOperator.IsNotNull;
                        else
                            condition.Operator = ConditionOperator.IsNull;
                    }
                    else
                    {
                        condition.Operator = ConditionOperator.Equals;
                        condition.Value = valueAttribute.Value;
                    }
                    csdlAssociation.Mapping.ConditionsMapping.Add(condition);
                }
                csdlAssociation.Mapping.SSDLTableMapped = table;
                csdlAssociation.Mapping.EndInit();
            }
            #endregion Associations

            #region Functions
            foreach (var functionMappingElement in entityContainerMappingElement.Elements(XName.Get("FunctionImportMapping", mslNamespace.NamespaceName)))
                csdlContainer.Functions.GetByName(functionMappingElement.Attribute("FunctionImportName").Value).SSDLFunction = ssdlContainer.Functions.GetByName(GetName(functionMappingElement.Attribute("FunctionName").Value));
            #endregion Funtions

            return csdlContainer;
        }
Esempio n. 2
0
        public static CSDLContainer ReadXElement(XElement edmxRuntime)
        {
            XElement schemaElement = edmxRuntime.Element(XName.Get("ConceptualModels", edmxNamespace.NamespaceName)).Element(XName.Get("Schema", csdlNamespace.NamespaceName));
            
            if (schemaElement == null || schemaElement.IsEmpty)
            	return null;
            
            XElement entityContainerElement = schemaElement.Element(XName.Get("EntityContainer", csdlNamespace.NamespaceName));

            CSDLContainer csdlContainer = new CSDLContainer { Namespace = schemaElement.Attribute("Namespace").Value, Alias = schemaElement.Attribute("Alias").Value, Name = entityContainerElement.Attribute("Name").Value };

            #region EntityTypes
            while (true)
            {
                var typesEnumerator = (from ete in schemaElement.Elements(XName.Get("EntityType", csdlNamespace.NamespaceName))
                                       let eteName = ete.Attribute("Name").Value
                                       where !csdlContainer.EntityTypes.Any(et => et.Name == eteName)
                                       let baseTypeAttribute = ete.Attribute("BaseType")
                                       let baseType = baseTypeAttribute == null ? null : csdlContainer.EntityTypes.GetByName(GetName(baseTypeAttribute.Value))
                                       where baseTypeAttribute == null || baseType != null
                                       select new { EntityTypeElement = ete, Name = eteName, BaseType = baseType }).GetEnumerator();
                if (!typesEnumerator.MoveNext())
                    break;
                do
                {
                    var current = typesEnumerator.Current;
                    csdlContainer.EntityTypes.Add(ReadCSDLEntityType(schemaElement, entityContainerElement, current.EntityTypeElement, csdlContainer, current.Name, current.BaseType));
                } while (typesEnumerator.MoveNext());
            }
            #endregion EntityTypes

            #region Associations
            foreach (var association in csdlContainer.AssociationsCreated)
            {
                association.AssociationSetName = entityContainerElement.Elements(XName.Get("AssociationSet", csdlNamespace.NamespaceName)).First(ae => GetName(ae.Attribute("Association").Value) == association.Name).Attribute("Name").Value;
                if (association.PropertyEnd2.EntityType == null)
                {
                    var entityTypeName = schemaElement.Elements(XName.Get("Association", csdlNamespace.NamespaceName)).First(ae => ae.Attribute("Name").Value == association.Name).Elements(XName.Get("End", csdlNamespace.NamespaceName)).First(er => er.Attribute("Role").Value == association.PropertyEnd2Role).Attribute("Type").Value;
                    int dotIndex = entityTypeName.IndexOf(".");
                    if (dotIndex != -1)
                        entityTypeName = entityTypeName.Substring(dotIndex + 1);
                    var entityType = csdlContainer.EntityTypes.First(et => et.Name == entityTypeName); ;
                    entityType.NavigationProperties.Add(association.PropertyEnd2);
                }
            }
            #endregion Associations

            #region ComplexTypes
            foreach (var complexTypeElement in schemaElement.Elements(XName.Get("ComplexType", csdlNamespace.NamespaceName)))
            {
                var complexType = new ComplexType { Name = complexTypeElement.Attribute("Name").Value };
                ReadCSDLType(schemaElement, complexTypeElement, csdlContainer, complexType);
                csdlContainer.ComplexTypes.Add(complexType);
            }
            #endregion ComplexTypes

            #region Functions
            foreach (var functionElement in entityContainerElement.Elements(XName.Get("FunctionImport", csdlNamespace.NamespaceName)))
            {
                var function = new Function { Name = functionElement.Attribute("Name").Value };
                var returnTypeAttribute = functionElement.Attribute("ReturnType");
                if (returnTypeAttribute != null)
                {
                    var returnTypeValue = returnTypeAttribute.Value;
                    returnTypeValue = returnTypeValue.Remove(returnTypeValue.IndexOf(")")).Substring(returnTypeValue.IndexOf("(") + 1);
                    function.ScalarReturnType = GetScalarPropertyTypeFromAttribute(returnTypeValue);
                    if (function.ScalarReturnType == null)
                        function.EntityType = csdlContainer.EntityTypes.GetByName(GetName(returnTypeValue));
                }
                SetVisibilityValueFromAttribute(functionElement, "methodAccess", visibility => function.Visibility = visibility);

                #region Function parameters
                foreach (var parameterElement in functionElement.Elements(XName.Get("Parameter", csdlNamespace.NamespaceName)))
                {
                    var parameter = new FunctionParameter { Name = parameterElement.Attribute("Name").Value, Type = GetScalarPropertyTypeFromAttribute(parameterElement).Value };
                    SetEnumValueFromAttribute<ParameterMode>(parameterElement, "Mode", mode => parameter.Mode = mode);
                    SetIntValueFromAttribute(parameterElement, "Precision", precision => parameter.Precision = precision);
                    SetIntValueFromAttribute(parameterElement, "Scale", scale => parameter.Scale = scale);
                    SetIntValueFromAttribute(parameterElement, "MaxLength", maxLength => parameter.MaxLength = maxLength);
                    function.Parameters.Add(parameter);
                }
                #endregion Function parameters

                csdlContainer.Functions.Add(function);
            }
            #endregion Functions

            return csdlContainer;
        }
Esempio n. 3
0
 private static EntityType ReadCSDLEntityType(XElement schemaElement, XElement entityContainerElement, XElement entityTypeElement, CSDLContainer container, string typeName, EntityType baseType)
 {
     var entityType = new EntityType { Name = typeName, BaseType = baseType };
     SetBoolValueFromAttribute(entityTypeElement, "Abstract", isAbstract => entityType.Abstract = isAbstract);
     var entitySetElement = entityContainerElement.Elements(XName.Get("EntitySet", csdlNamespace.NamespaceName)).Where(ese => GetName(ese.Attribute("EntityType").Value) == entityType.Name).FirstOrDefault();
     if (entitySetElement != null)
     {
         entityType.EntitySetName = entitySetElement.Attribute("Name").Value;
         SetVisibilityValueFromAttribute(entitySetElement, "GetterAccess", getterAccess => entityType.EntitySetVisibility = getterAccess);
     }
     ReadCSDLType(schemaElement, entityTypeElement, container, (TypeBase)entityType);
     return entityType;
 }
Esempio n. 4
0
        private static void ReadCSDLType(XElement schemaElement, XElement entityTypeElement, CSDLContainer container, TypeBase baseType)
        {
            if (baseType.Name == null)
                baseType.Name = entityTypeElement.Attribute("Name").Value;
            SetVisibilityValueFromAttribute(entityTypeElement, "TypeAccess", typeAccess => baseType.Visibility = typeAccess);

            foreach (var propertyElement in entityTypeElement.Elements(XName.Get("Property", csdlNamespace.NamespaceName)))
            {
                var name = propertyElement.Attribute("Name").Value;
                var keyElement = entityTypeElement.Element(XName.Get("Key", csdlNamespace.NamespaceName));
                var propertyType = GetScalarPropertyTypeFromAttribute(propertyElement);
                PropertyBase property;
                if (propertyType == null)
                {
                    property = new ComplexProperty(GetName(propertyElement.Attribute("Type").Value)) { Name = name };
                    baseType.ComplexProperties.Add((ComplexProperty)property);
                }
                else
                {
                    property = new ScalarProperty() { Name = name, IsKey = keyElement != null && keyElement.Elements(XName.Get("PropertyRef", csdlNamespace.NamespaceName)).Where(pr => pr.Attribute("Name").Value == name).Any(), Type = propertyType.Value };
                    var scalarProp = (ScalarProperty)property;
                    SetBoolValueFromAttribute(propertyElement, "Nullable", nullable => scalarProp.Nullable = nullable);
                    SetVisibilityValueFromAttribute(propertyElement, "SetterAccess", setterAccess => scalarProp.SetVisibility = setterAccess);
                    SetIntValueFromAttribute(propertyElement, "MaxLength", maxLength => scalarProp.MaxLength = maxLength);
                    SetBoolValueFromAttribute(propertyElement, "Unicode", unicode => scalarProp.Unicode = unicode);
                    SetBoolValueFromAttribute(propertyElement, "FixedLength", fixedLength => scalarProp.FixedLength = fixedLength);
                    SetIntValueFromAttribute(propertyElement, "Precision", precision => scalarProp.Precision = precision);
                    SetIntValueFromAttribute(propertyElement, "Scale", scale => scalarProp.Scale = scale);
                    SetStringValueFromAttribute(propertyElement, "ConcurrencyMode", concurrencyMode => scalarProp.ConcurrencyMode = ConcurrencyMode.None);
                    SetStringValueFromAttribute(propertyElement, "DefaultValue", defaultValue => scalarProp.DefaultValue = defaultValue);
                    SetStringValueFromAttribute(propertyElement, "Collation", collation => scalarProp.Collation = collation);
                    baseType.ScalarProperties.Add(scalarProp);
                }
                SetVisibilityValueFromAttribute(propertyElement, "GetterAccess", getterAccess => property.GetVisibility = getterAccess);
            }
            var entityType = baseType as EntityType;
            if (entityType != null)
            {
                foreach (var navigationPropertyElement in entityTypeElement.Elements(XName.Get("NavigationProperty", csdlNamespace.NamespaceName)))
                {
                    var navigationPropertyname = navigationPropertyElement.Attribute("Name").Value;
                    var associationName = GetName(navigationPropertyElement.Attribute("Relationship").Value);
                    var associationElement = schemaElement.Elements(XName.Get("Association", csdlNamespace.NamespaceName)).First(ae => ae.Attribute("Name").Value == associationName);
                    Association association = container.AssociationsCreated.GetByName(associationName);
                    bool associationExisting = association != null;
                    if (!associationExisting)
                    {
                        association = new Association { Name = associationName };
                        container.AssociationsCreated.Add(association);
                    }
                    var navigationProperty = new NavigationProperty(association) { Name = navigationPropertyname };
                    var roleName = navigationPropertyElement.Attribute("FromRole").Value;
                    SetCardinalityValueFromAttribute(associationElement.Elements(XName.Get("End", csdlNamespace.NamespaceName)).First(ee => ee.Attribute("Role").Value == roleName), cardinality => navigationProperty.Cardinality = cardinality);
                    SetVisibilityValueFromAttribute(navigationPropertyElement, "GetterAccess", visibility => navigationProperty.GetVisibility = visibility);
                    SetVisibilityValueFromAttribute(navigationPropertyElement, "SetterAccess", visibility => navigationProperty.SetVisibility = visibility);
                    if (associationExisting)
                    {
                        association.PropertyEnd2 = navigationProperty;
                        association.PropertyEnd2Role = roleName;
                    }
                    else
                    {
                        association.PropertyEnd1 = navigationProperty;
                        association.PropertyEnd1Role = roleName;
                        string toRoleName = navigationPropertyElement.Attribute("ToRole").Value;
                        NavigationProperty fakeNavigationProperty = new NavigationProperty(association) { Name = roleName, Generate = false };
                        SetCardinalityValueFromAttribute(associationElement.Elements(XName.Get("End", csdlNamespace.NamespaceName)).First(ee => ee.Attribute("Role").Value == toRoleName), cardinality => fakeNavigationProperty.Cardinality = cardinality);
                        association.PropertyEnd2 = fakeNavigationProperty;
                        association.PropertyEnd2Role = toRoleName;
                    }
                    var referentialConstraintElement = associationElement.Element(XName.Get("ReferentialConstraint", csdlNamespace.NamespaceName));
                    if (referentialConstraintElement != null)
                    {
                        var referentialConstraintRoleElement = referentialConstraintElement.Elements().First(rce => rce.Attribute("Role").Value == roleName);
                        var scalarProperties = referentialConstraintRoleElement.Elements(XName.Get("PropertyRef", csdlNamespace.NamespaceName)).Select(e => entityType.AllScalarProperties.First(sp => sp.Name == e.Attribute("Name").Value));
                        switch (referentialConstraintRoleElement.Name.LocalName)
                        {
                            case "Principal":
                                association.PrincipalRole = roleName;
                                association.PrincipalProperties = scalarProperties;
                                break;
                            case "Dependent":
                                association.DependentRole = roleName;
                                association.DependentProperties = scalarProperties;
                                break;
                            default:
                                throw new NotImplementedException();
                        }
                    }
                    entityType.NavigationProperties.Add(navigationProperty);
                }
            }
        }
Esempio n. 5
0
        public static XElement Write(CSDLContainer csdlContainer)
        {
            // Instantiate Schema
            XElement schema = new XElement(csdlNamespace + "Schema",
                new XAttribute("Namespace", csdlContainer.Namespace),
                new XAttribute("Alias", csdlContainer.Alias),
                new XAttribute(XNamespace.Xmlns + "annotation", csdlAnnotationNamespace.NamespaceName),
                new XAttribute("xmlns", csdlNamespace.NamespaceName));

            // EntityContainer
            string entityContainerNamespace = string.Concat(csdlContainer.Namespace, ".");
            XElement entityContainer = new XElement(csdlNamespace + "EntityContainer", new XAttribute("Name", csdlContainer.Name));
            schema.Add(entityContainer);

            // EntityContainer : EntitySets
            foreach (EntityType entityType in csdlContainer.EntitySets)
            {
                XElement entitySetElement = new XElement(csdlNamespace + "EntitySet",
                    new XAttribute("Name", entityType.EntitySetName), 
                    new XAttribute("EntityType", string.Concat(entityContainerNamespace, entityType.Name)));
                    //.AddAttribute(csdlCodeGenerationNamespace, "GetterAccess", entityType.EntitySetVisibility); // Not available in EF 4.0

                entityContainer.Add(entitySetElement);
            }

            // EntityContainer : AssociationSets
            foreach (Association association in csdlContainer.Associations)
            {
                XElement associationSetElement = new XElement(csdlNamespace + "AssociationSet",
                    new XAttribute("Name", association.AssociationSetName),
                    new XAttribute("Association", string.Concat(entityContainerNamespace, association.Name)));

                associationSetElement.Add(
                    new XElement(csdlNamespace + "End", new XAttribute("Role", association.PropertyEnd1Role), new XAttribute("EntitySet", association.PropertyEnd1.EntityType.EntitySetName)),
                    new XElement(csdlNamespace + "End", new XAttribute("Role", association.PropertyEnd2Role), new XAttribute("EntitySet", association.PropertyEnd2.EntityType.EntitySetName)));

                entityContainer.AddElement(associationSetElement);
            }

            // EntityContainer : FunctionImports
            foreach (Function function in csdlContainer.Functions)
            {
                XElement functionElement = new XElement(csdlNamespace + "FunctionImport",
                    new XAttribute("Name", function.Name))
                    .AddAttribute("EntitySet", function.EntityType == null ? null : function.EntityType.EntitySetName)
                    .AddAttribute("ReturnType", function.ReturnType);

                foreach (FunctionParameter functionParameter in function.Parameters)
                {
                    functionElement.AddElement(new XElement(csdlNamespace + "Paramter",
                        new XAttribute("Name", functionParameter.Name),
                        new XAttribute("Type", functionParameter.Type))
                        .AddAttribute("MaxLength", functionParameter.MaxLength)
                        .AddAttribute("Mode", functionParameter.Mode)
                        .AddAttribute("Precision", functionParameter.Precision)
                        .AddAttribute("Scale", functionParameter.Scale));
                }

                entityContainer.AddElement(functionElement);
            }

            // ComplexTypes
            foreach (ComplexType complexType in csdlContainer.ComplexTypes)
            {
                XElement complexTypeElement = new XElement(csdlNamespace + "ComplexType",
                    new XAttribute("Name", complexType.Name));
                    //.AddAttribute(new XAttribute(csdlCodeGenerationNamespace + "TypeAccess", complexType.Visibility)); // Not available in EF 4.0

                complexTypeElement.Add(WriteScalarProperties(complexType));
                complexTypeElement.Add(WriteComplexProperties(complexType, string.Concat(csdlContainer.Alias, ".")));

                schema.AddElement(complexTypeElement);
            }

            // EntityTypes
            foreach (EntityType entityType in csdlContainer.EntityTypes)
            {
                XElement entityTypeElement = new XElement(csdlNamespace + "EntityType")
                    .AddAttribute("Name", entityType.Name)
                    //.AddAttribute(csdlCodeGenerationNamespace, "TypeAccess", entityType.Visibility) // Not available in EF 4.0
                    .AddAttribute("BaseType", entityType.BaseType == null ? null : string.Concat(entityContainerNamespace, entityType.BaseType.Name))
                    .AddAttribute("Abstract", entityType.Abstract);

                if (entityType.SpecificKeys.Any())
                {
                    XElement keyElement = new XElement(csdlNamespace + "Key");
                    
                    entityType.ScalarProperties.Where(sp => sp.IsKey).ForEach(scalarProperty =>
                    {
                        keyElement.AddElement(new XElement(csdlNamespace + "PropertyRef")
                            .AddAttribute("Name", scalarProperty.Name));                        
                    });

                    entityTypeElement.AddElement(keyElement);
                }

                entityTypeElement.Add(WriteScalarProperties(entityType));
                entityTypeElement.Add(WriteComplexProperties(entityType, string.Concat(csdlContainer.Alias, ".")));

                // EntityType : NavigationProperties
                entityType.NavigationProperties.Where(np => np.Generate).ForEach(navigationProperty =>
                {
                    entityTypeElement.AddElement(new XElement(csdlNamespace + "NavigationProperty")
                        .AddAttribute("Name", navigationProperty.Name)
                        .AddAttribute("Relationship", string.Concat(entityContainerNamespace, navigationProperty.Association.Name))
                        .AddAttribute("FromRole", navigationProperty.Association.GetRoleName(navigationProperty))
                        .AddAttribute("ToRole", navigationProperty.Association.GetRoleName(navigationProperty.Association.PropertiesEnd.First(role => role != navigationProperty))));
                        //.AddAttribute(csdlCodeGenerationNamespace, "GetterAccess", navigationProperty.GetVisibility) // Not available in EF 4.0
                        //.AddAttribute(csdlCodeGenerationNamespace, "SetterAccess", navigationProperty.SetVisibility));
                });

                schema.AddElement(entityTypeElement);
            }

            // Associations
            foreach (Association association in csdlContainer.Associations)
            { 
                XElement associationElement = new XElement(csdlNamespace + "Association")
                    .AddAttribute("Name", association.Name);
                    
                associationElement.AddElement(new XElement(csdlNamespace + "End")
                    .AddAttribute("Role", association.PropertyEnd1Role)
                    .AddAttribute("Type", string.Concat(entityContainerNamespace, association.PropertyEnd1.EntityType.Name))
                    .AddAttribute("Multiplicity", CardinalityStringConverter.CardinalityToString(association.PropertyEnd1.Cardinality)));

                associationElement.AddElement(new XElement(csdlNamespace + "End")
                    .AddAttribute("Role", association.PropertyEnd2Role)
                    .AddAttribute("Type", string.Concat(entityContainerNamespace, association.PropertyEnd2.EntityType.Name))
                    .AddAttribute("Multiplicity", CardinalityStringConverter.CardinalityToString(association.PropertyEnd2.Cardinality)));

                if (association.PrincipalRole != null)
                { 
                    XElement referentialConstraintElement = new XElement(csdlNamespace + "ReferentialConstraint");

                    XElement principalElement = (new XElement(csdlNamespace + "Principal")
                        .AddAttribute("Role", association.PrincipalRole));

                    foreach (ScalarProperty propertyRef in association.PrincipalProperties)
                        principalElement.AddElement(new XElement(csdlNamespace + "PropertyRef").AddAttribute("Name", propertyRef.Name));

                    XElement dependentElement = (new XElement(csdlNamespace + "Dependent")
                        .AddAttribute("Role", association.DependentRole));

                    foreach (ScalarProperty propertyRef in association.DependentProperties)
                        dependentElement.AddElement(new XElement(csdlNamespace + "PropertyRef").AddAttribute("Name", propertyRef.Name));

                    referentialConstraintElement.AddElement(principalElement);
                    referentialConstraintElement.AddElement(dependentElement);
                    associationElement.AddElement(referentialConstraintElement);
                }

                schema.AddElement(associationElement);
            }

            return schema;
        }