예제 #1
0
        public static SSDLContainer CreateSSDLContainer(IDatabase database, string modelNamespace)
        {
            SSDLContainer ssdlContainer = new SSDLContainer()
            {
                Name = database.Name.Replace(".", string.Empty) + "StoreContainer",
                Namespace = modelNamespace,
                Provider = database.Datasource.DatabaseDriver.ProviderName,
                ProviderManifestToken = database.Datasource.ProviderManifestToken
            };

            List<ITable> tablesAndViews = new List<ITable>();
            tablesAndViews.AddRange(database.Tables);
            tablesAndViews.AddRange(database.Views);

            foreach (ITable table in tablesAndViews)
            {
                if (!table.IsSelected)
                    continue;

                EntityType entityType = CreateSSDLEntityType(table);
                ssdlContainer.EntityTypes.Add(entityType);

                if (table.Constraints != null)
                {
                    foreach (IConstraint constraint in table.Constraints)
                    {
                        if (constraint.FKTableName != table.TableName)
                            continue;

                        Association association = CreateSSDLAssociation(constraint);
                        ssdlContainer.AssociationSets.Add(association);
                    }
                }
            }

            foreach (IProcedure procedure in database.Procedures)
            {
                if (!procedure.IsSelected)
                    continue;
                
                Function function = CreateSSDLFunction(procedure);
                ssdlContainer.Functions.Add(function);
            }

            return ssdlContainer;
        }
예제 #2
0
파일: MSLIO.cs 프로젝트: hpsa/SharpDevelop
        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;
        }
예제 #3
0
파일: MSLIO.cs 프로젝트: hpsa/SharpDevelop
 private static CUDFunctionMapping SetCUDFunctionMapping(SSDLContainer ssdlContainer, EntityType entityType, XElement functionMappingElement)
 {
     var cudFunctionMapping = new CUDFunctionMapping();
     var ssdlFunction = ssdlContainer.Functions.GetByName(GetName(functionMappingElement.Attribute("FunctionName").Value));
     cudFunctionMapping.SSDLFunction = ssdlFunction;
     SetCUDFunctionParametersMapping(entityType, functionMappingElement, cudFunctionMapping.ParametersMapping, ssdlFunction);
     foreach (var scalarPropertyElement in functionMappingElement.Elements(XName.Get("ResultBinding", mslNamespace.NamespaceName)))
         cudFunctionMapping.ResultsMapping[entityType.AllScalarProperties.GetByName(scalarPropertyElement.Attribute("Name").Value)] = scalarPropertyElement.Attribute("ColumnName").Value;
     foreach (var associationEndElement in functionMappingElement.Elements(XName.Get("AssociationEnd", mslNamespace.NamespaceName)))
     {
         var navigationProperty = entityType.NavigationProperties.First(np => np.Association.AssociationSetName == associationEndElement.Attribute("AssociationSet").Value);
         var cudFunctionAssociationMapping = new CUDFunctionAssociationMapping { Association = navigationProperty.Association, FromRole = associationEndElement.Attribute("From").Value, ToRole = associationEndElement.Attribute("To").Value };
         cudFunctionMapping.AssociationMappings.Add(cudFunctionAssociationMapping);
         SetCUDFunctionParametersScalarMapping(navigationProperty.RelatedEntityType, associationEndElement, cudFunctionAssociationMapping.AssociationPropertiesMapping, ssdlFunction);
     }
     return cudFunctionMapping;
 }
예제 #4
0
        public static XElement WriteXElement(SSDLContainer ssdlContainer)
        {
            // Instantiate Schema
            XElement schema = new XElement(ssdlNamespace + "Schema",
                new XAttribute("Namespace", ssdlContainer.Namespace), 
                new XAttribute("Alias", "Self"),
                new XAttribute(XNamespace.Xmlns + "store", storeNamespace.NamespaceName),
                new XAttribute("xmlns", ssdlNamespace.NamespaceName))
                .AddAttribute("Provider", ssdlContainer.Provider)
                .AddAttribute("ProviderManifestToken", ssdlContainer.ProviderManifestToken);
            
            // EntityContainer
            string entityContainerNamespace = string.Concat(ssdlContainer.Namespace, ".");
            XElement entityContainer = new XElement(ssdlNamespace + "EntityContainer", new XAttribute("Name", ssdlContainer.Name));
            schema.Add(entityContainer);

            // EntityContainer : EntitySets
            foreach (EntityType entityType in ssdlContainer.EntityTypes)
            {
                XElement entitySet = new XElement(ssdlNamespace + "EntitySet",
                    new XAttribute("Name", entityType.EntitySetName), new XAttribute("EntityType", string.Concat(entityContainerNamespace, entityType.Name)))
                        .AddAttribute(entityType.StoreType == StoreType.Views ? null : new XAttribute("Schema", entityType.Schema))
                        .AddAttribute("Table", entityType.Table)
                        .AddAttribute(storeNamespace, "Name", entityType.StoreName)
                        .AddAttribute(storeNamespace, "Schema", entityType.StoreSchema)
                        .AddAttribute(storeNamespace, "Type", entityType.StoreType)
                        .AddElement(string.IsNullOrEmpty(entityType.DefiningQuery) ? null : new XElement(ssdlNamespace + "DefiningQuery", entityType.DefiningQuery));

                entityContainer.Add(entitySet);
            }

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

                string role2Name = association.Role2.Name;

                // If the association end properties are the same properties
                if (association.Role1.Name == association.Role2.Name && association.Role1.Type.Name == association.Role2.Type.Name)
                    role2Name += "1";

                associationSet.Add(
                        new XElement(ssdlNamespace + "End", new XAttribute("Role", association.Role1.Name), new XAttribute("EntitySet", association.Role1.Type.Name)),
                        new XElement(ssdlNamespace + "End", new XAttribute("Role", role2Name), new XAttribute("EntitySet", association.Role2.Type.Name)));
            
                entityContainer.Add(associationSet);
            }

            // EntityTypes
            foreach (EntityType entityType in ssdlContainer.EntityTypes)
            {
                XElement entityTypeElement = new XElement(ssdlNamespace + "EntityType", new XAttribute("Name", entityType.Name));

                XElement keys = new XElement(ssdlNamespace + "Key");

                foreach (Property property in entityType.Properties)
                {
                    // If we have a table then we set a key element if the current property is a primary key or part of a composite key.
                    // AND: If we have a view then we make a composite key of all non-nullable properties of the entity (VS2010 is also doing this).
                    if ((entityType.StoreType == StoreType.Tables && property.IsKey) || (entityType.StoreType == StoreType.Views && property.Nullable == false))
                        keys.Add(new XElement(ssdlNamespace + "PropertyRef", new XAttribute("Name", property.Name)));
                }

                if (!keys.IsEmpty)
                    entityTypeElement.Add(keys);

                foreach (Property property in entityType.Properties)
                {
                    entityTypeElement.Add(new XElement(ssdlNamespace + "Property", new XAttribute("Name", property.Name), new XAttribute("Type", property.Type))
                        .AddAttribute("Collation", property.Collation)
                        .AddAttribute("DefaultValue", property.DefaultValue)
                        .AddAttribute("FixedLength", property.FixedLength)
                        .AddAttribute("MaxLength", property.MaxLength)
                        .AddAttribute("Nullable", property.Nullable)
                        .AddAttribute("Precision", property.Precision)
                        .AddAttribute("Scale", property.Scale)
                        .AddAttribute("StoreGeneratedPattern", property.StoreGeneratedPattern)
                        .AddAttribute(storeNamespace, "Name", property.StoreName)
                        .AddAttribute(storeNamespace, "Schema", property.StoreSchema)
                        .AddAttribute(storeNamespace, "Type", property.StoreType)
                        .AddAttribute("Unicode", property.Unicode));
                }

                schema.AddElement(entityTypeElement);
            }

            foreach (Association association in ssdlContainer.AssociationSets)
            {
                string role2Name = association.Role2.Name;

                // If the association end properties are the same properties
                if (association.Role1.Name == association.Role2.Name && association.Role1.Type.Name == association.Role2.Type.Name)
                    role2Name += "1";
                
                XElement associationElement = new XElement(ssdlNamespace + "Association", new XAttribute("Name", association.Name),
                        new XElement(ssdlNamespace + "End", new XAttribute("Role", association.Role1.Name), new XAttribute("Type", string.Concat(entityContainerNamespace, association.Role1.Type.Name)), new XAttribute("Multiplicity", CardinalityStringConverter.CardinalityToString(association.Role1.Cardinality))),
                        new XElement(ssdlNamespace + "End", new XAttribute("Role", role2Name), new XAttribute("Type", string.Concat(entityContainerNamespace, association.Role2.Type.Name)), new XAttribute("Multiplicity", CardinalityStringConverter.CardinalityToString(association.Role2.Cardinality))));

                string dependentRoleName = association.DependantRole.Name;

                // If the association end properties are the same properties
                if (association.PrincipalRole.Name == association.DependantRole.Name && association.PrincipalRole.Type.Name == association.DependantRole.Type.Name)
                    dependentRoleName += "1";

                XElement principalRoleElement = new XElement(ssdlNamespace + "Principal", new XAttribute("Role", association.PrincipalRole.Name));
                foreach (Property property in association.PrincipalRole.Properties)
                    principalRoleElement.Add(new XElement(ssdlNamespace + "PropertyRef", new XAttribute("Name", property.Name)));

                XElement dependentRoleElement = new XElement(ssdlNamespace + "Dependent", new XAttribute("Role", dependentRoleName));
                foreach (Property property in association.DependantRole.Properties)
                    dependentRoleElement.Add(new XElement(ssdlNamespace + "PropertyRef", new XAttribute("Name", property.Name)));

                XElement referentialConstraintElement = new XElement(ssdlNamespace + "ReferentialConstraint", principalRoleElement, dependentRoleElement);
                associationElement.Add(referentialConstraintElement);

                schema.Add(associationElement);
            }

            foreach (Function function in ssdlContainer.Functions)
            {
                XElement functionElement = new XElement(ssdlNamespace + "Function", new XAttribute("Name", function.Name))
                    .AddAttribute("Aggregate", function.Aggregate)
                    .AddAttribute("BuiltIn", function.BuiltIn)
                    .AddAttribute("CommandText", function.CommandText)
                    .AddAttribute("IsComposable", function.IsComposable)
                    .AddAttribute("NiladicFunction", function.NiladicFunction)
                    .AddAttribute("ReturnType", function.ReturnType)
                    .AddAttribute("StoreFunctionName", function.StoreFunctionName)
                    .AddAttribute("ParameterTypeSemantics", function.ParameterTypeSemantics)
                    .AddAttribute("Schema", function.Schema)
                    .AddAttribute(storeNamespace, "Name", function.StoreName)
                    .AddAttribute(storeNamespace, "Schema", function.StoreSchema)
                    .AddAttribute(storeNamespace, "Type", function.StoreType);

                foreach (FunctionParameter functionParameter in function.Parameters)
                {
                    functionElement.Add(new XElement(ssdlNamespace + "Parameter", 
                        new XAttribute("Name", functionParameter.Name), new XAttribute("Type", functionParameter.Type), new XAttribute("Mode", functionParameter.Mode))
                            .AddAttribute("MaxLength", functionParameter.MaxLength)
                            .AddAttribute("Precision", functionParameter.Precision)
                            .AddAttribute("Scale", functionParameter.Scale)
                            .AddAttribute(storeNamespace, "Name", functionParameter.StoreName)
                            .AddAttribute(storeNamespace, "Schema", functionParameter.StoreSchema)
                            .AddAttribute(storeNamespace, "Type", functionParameter.StoreType));
                }

                schema.Add(functionElement);
            }

            return schema;
        }
예제 #5
0
 public static XDocument WriteXDocument(SSDLContainer ssdlContainer)
 {
     return new XDocument(new XDeclaration("1.0", "utf-8", null), WriteXElement(ssdlContainer));
 }
예제 #6
0
        public static SSDLContainer ReadXElement(XElement ssdlXElement)
        {
            XElement schemaElement = ssdlXElement.Element(XName.Get("StorageModels", edmxNamespace.NamespaceName)).Element(XName.Get("Schema", ssdlNamespace.NamespaceName));
            
            if (schemaElement == null || schemaElement.IsEmpty)
            	return null;
            
            XElement entityContainerElement = schemaElement.Element(XName.Get("EntityContainer", ssdlNamespace.NamespaceName));

            var value = new SSDLContainer { Namespace = schemaElement.Attribute("Namespace").Value, Name = entityContainerElement.Attribute("Name").Value };
            SetStringValueFromAttribute(schemaElement, "Provider", provider => value.Provider = provider);
            SetStringValueFromAttribute(schemaElement, "ProviderManifestToken", provider => value.ProviderManifestToken = provider);

            #region EntitySets

            foreach (var entitySetElement in entityContainerElement.Elements(XName.Get("EntitySet", ssdlNamespace.NamespaceName)))
            {
                var entityType = new EntityType { EntitySetName = entitySetElement.Attribute("Name").Value };
                var entityTypeName = GetName(entitySetElement.Attribute("EntityType").Value);
                entityType.Name = entityTypeName;
                SetEnumValueFromAttribute<StoreType>(entitySetElement, "Type", storeNamespace.NamespaceName, storeType => entityType.StoreType = storeType);
                SetStringValueFromAttribute(entitySetElement, "Schema", schema => entityType.Schema = schema);
                SetStringValueFromAttribute(entitySetElement, "Name", storeNamespace.NamespaceName, storeName => entityType.StoreName = storeName);
                SetStringValueFromAttribute(entitySetElement, "Schema", storeNamespace.NamespaceName, storeSchema => entityType.StoreSchema = storeSchema);
                SetStringValueFromAttribute(entitySetElement, "Table", table => entityType.Table = table);
                SetStringValueFromElement(entitySetElement, "DefiningQuery", ssdlNamespace.NamespaceName, query => entityType.DefiningQuery = query);

                #region Properties
                var entityTypeElement = schemaElement.Elements(XName.Get("EntityType", ssdlNamespace.NamespaceName)).First(etElement => etElement.Attribute("Name").Value == entityTypeName);
                foreach (var propertyElement in entityTypeElement.Elements(XName.Get("Property", ssdlNamespace.NamespaceName)))
                {
                    var name = propertyElement.Attribute("Name").Value;
                    var property = new Property(entityType) { Name = name, Type = propertyElement.Attribute("Type").Value, IsKey = entityTypeElement.Element(XName.Get("Key", ssdlNamespace.NamespaceName)).Elements(XName.Get("PropertyRef", ssdlNamespace.NamespaceName)).Any(pr => pr.Attribute("Name").Value == name) };
                    SetBoolValueFromAttribute(propertyElement, "Nullable", nullable => property.Nullable = nullable);
                    SetIntValueFromAttribute(propertyElement, "MaxLength", maxLength => property.MaxLength = maxLength);
                    SetBoolValueFromAttribute(propertyElement, "FixedLength", fixedLength => property.FixedLength = fixedLength);
                    SetIntValueFromAttribute(propertyElement, "Precision", precision => property.Precision = precision);
                    SetIntValueFromAttribute(propertyElement, "Scale", scale => property.Scale = scale);
                    SetStringValueFromAttribute(propertyElement, "Collation", collation => property.Collation = collation);
                    SetStringValueFromAttribute(propertyElement, "DefaultValue", defaultValue => property.DefaultValue = defaultValue);
                    SetBoolValueFromAttribute(propertyElement, "Unicode", unicode => property.Unicode = unicode);
                    SetEnumValueFromAttribute<StoreGeneratedPattern>(propertyElement, "StoreGeneratedPattern", storeGeneratedPattern => property.StoreGeneratedPattern = storeGeneratedPattern);
                    SetStringValueFromAttribute(propertyElement, "Name", storeNamespace.NamespaceName, storeName => property.StoreName = storeName);
                    SetStringValueFromAttribute(propertyElement, "Schema", storeNamespace.NamespaceName, storeSchema => property.StoreSchema = storeSchema);
                    SetStringValueFromAttribute(propertyElement, "Type", storeNamespace.NamespaceName, storeType => property.StoreType = storeType);
                    entityType.Properties.Add(property);
                }
                #endregion Properties

                value.EntityTypes.Add(entityType);
            }

            #endregion EntitySets

            #region AssociationSets

            foreach (var associationSetElement in entityContainerElement.Elements(XName.Get("AssociationSet", ssdlNamespace.NamespaceName)))
            {
                var association = new Association { AssociationSetName = associationSetElement.Attribute("Name").Value };
                var associationName = GetName(associationSetElement.Attribute("Association").Value);
                association.Name = associationName;

                #region Roles
                var associationElement = schemaElement.Elements(XName.Get("Association", ssdlNamespace.NamespaceName)).First(aElement => aElement.Attribute("Name").Value == associationName);
                bool isPrincipal = true;
                foreach (var roleElement in associationSetElement.Elements(XName.Get("End", ssdlNamespace.NamespaceName)))
                {
                    var roleName = roleElement.Attribute("Role").Value;
                    var role = new Role { Name = roleName, Type = value.EntityTypes.GetByName(roleElement.Attribute("EntitySet").Value) };
                    SetCardinalityValueFromAttribute(associationElement.Elements(XName.Get("End", ssdlNamespace.NamespaceName)).First(are => are.Attribute("Role").Value == roleName), cardinality => role.Cardinality = cardinality);
                    var referentialConstraintElement = associationElement.Element(XName.Get("ReferentialConstraint", ssdlNamespace.NamespaceName));
                    if (referentialConstraintElement != null)
                    {
                        var principalElement = referentialConstraintElement.Element(XName.Get("Principal", ssdlNamespace.NamespaceName));
                        if (principalElement.Attribute("Role").Value == role.Name)
                        {
                            isPrincipal = true;
                            association.PrincipalRole = role;

                            EventedObservableCollection<Property> properties = new EventedObservableCollection<Property>();

                            foreach (XElement element in principalElement.Elements(XName.Get("PropertyRef", ssdlNamespace.NamespaceName)))
                            {
                                foreach (Property property in role.Type.Properties)
                                {
                                    if (property.Name == element.Attribute("Name").Value)
                                        properties.Add(property);
                                }
                            }

                            role.Properties = properties;
                        }
                        else
                        {
                            isPrincipal = false;
                            association.DependantRole = role;

                            EventedObservableCollection<Property> properties = new EventedObservableCollection<Property>();
                            XElement dependentElement = referentialConstraintElement.Element(XName.Get("Dependent", ssdlNamespace.NamespaceName));

                            foreach (XElement element in dependentElement.Elements(XName.Get("PropertyRef", ssdlNamespace.NamespaceName)))
                            {
                                foreach (Property property in role.Type.Properties)
                                {
                                    if (property.Name == element.Attribute("Name").Value)
                                        properties.Add(property);
                                }
                            }

                            role.Properties = properties;
                        }
                    }
                    if (isPrincipal)
                    {
                        association.Role1 = role;
                        isPrincipal = false;
                    }
                    else
                        association.Role2 = role;
                }

                #endregion Roles

                value.AssociationSets.Add(association);
            }

            #endregion AssociationSets

            #region Functions

            foreach (var functionElement in schemaElement.Elements(XName.Get("Function", ssdlNamespace.NamespaceName)))
            {
                var function = new Function { Name = functionElement.Attribute("Name").Value };
                SetBoolValueFromAttribute(functionElement, "Aggregate", aggregate => function.Aggregate = aggregate);
                SetBoolValueFromAttribute(functionElement, "BuiltIn", builtIn => function.BuiltIn = builtIn);
                SetBoolValueFromAttribute(functionElement, "IsComposable", isComposable => function.IsComposable = isComposable);
                SetBoolValueFromAttribute(functionElement, "NiladicFunction", niladicFunction => function.NiladicFunction = niladicFunction);
                SetStringValueFromAttribute(functionElement, "Schema", schema => function.Schema = schema);
                SetStringValueFromAttribute(functionElement, "Name", storeNamespace.NamespaceName, name => function.StoreName = name);
                SetStringValueFromAttribute(functionElement, "Schema", storeNamespace.NamespaceName, schema => function.StoreSchema = schema);
                SetStringValueFromAttribute(functionElement, "Type", storeNamespace.NamespaceName, type => function.StoreType = type);
                SetStringValueFromAttribute(functionElement, "FunctionName", storeNamespace.NamespaceName, functionName => function.StoreFunctionName = functionName);
                SetEnumValueFromAttribute<ParameterTypeSemantics>(functionElement, "ParameterTypeSemantics", parameterTypeSemantics => function.ParameterTypeSemantics = parameterTypeSemantics);

                #region Parameters

                foreach (var parameterElement in functionElement.Elements(XName.Get("Parameter", ssdlNamespace.NamespaceName)))
                {
                    var parameter = new FunctionParameter { Name = parameterElement.Attribute("Name").Value, Type = parameterElement.Attribute("Type").Value };
                    SetEnumValueFromAttribute<ParameterMode>(parameterElement, "Mode", mode => parameter.Mode = mode);
                    SetIntValueFromAttribute(parameterElement, "MaxLength", maxLength => parameter.MaxLength = maxLength);
                    SetIntValueFromAttribute(parameterElement, "Precision", precision => parameter.Precision = precision);
                    SetIntValueFromAttribute(parameterElement, "Scale", scale => parameter.Scale = scale);
                    SetStringValueFromAttribute(parameterElement, "Name", storeNamespace.NamespaceName, name => parameter.StoreName = name);
                    SetStringValueFromAttribute(parameterElement, "Schema", storeNamespace.NamespaceName, schema => parameter.StoreSchema = schema);
                    SetStringValueFromAttribute(parameterElement, "Type", storeNamespace.NamespaceName, type => parameter.StoreType = type);

                    function.Parameters.Add(parameter);
                }

                #endregion Parameters

                value.Functions.Add(function);
            }

            #endregion Functions

            return value;
        }