private void WritePropertyMapping(StorageComplexPropertyMapping complexPropertyMapping)
        {
            _xmlWriter.WriteStartElement(StorageMslConstructs.ComplexPropertyElement);
            _xmlWriter.WriteAttributeString(StorageMslConstructs.ComplexPropertyNameAttribute, complexPropertyMapping.EdmProperty.Name);
            _xmlWriter.WriteAttributeString(
                StorageMslConstructs.ComplexPropertyTypeNameAttribute,
                _entityTypeNamespace + "." + complexPropertyMapping.EdmProperty.ComplexType.Name);

            foreach (var propertyMapping in complexPropertyMapping.TypeMappings.Single().Properties)
            {
                WritePropertyMapping(propertyMapping);
            }

            _xmlWriter.WriteEndElement();
        }
Пример #2
0
 /// <summary>
 /// Returns all bottom-level mappings (e.g. conditions and scalar property mappings but not complex property mappings
 /// whose components are returned)
 /// </summary>
 private static IEnumerable <StoragePropertyMapping> FlattenPropertyMappings(System.Collections.ObjectModel.ReadOnlyCollection <StoragePropertyMapping> propertyMappings)
 {
     foreach (StoragePropertyMapping propertyMapping in propertyMappings)
     {
         StorageComplexPropertyMapping complexPropertyMapping = propertyMapping as StorageComplexPropertyMapping;
         if (null != complexPropertyMapping)
         {
             foreach (StorageComplexTypeMapping complexTypeMapping in complexPropertyMapping.TypeMappings)
             {
                 // recursively call self with nested type
                 foreach (StoragePropertyMapping nestedPropertyMapping in FlattenPropertyMappings(complexTypeMapping.AllProperties))
                 {
                     yield return(nestedPropertyMapping);
                 }
             }
         }
         else
         {
             yield return(propertyMapping);
         }
     }
 }
        // requires: "properties" corresponds to all the properties that are
        // inside cNode.Value, e.g., cNode corresponds to an extent Person,
        // properties contains all the properties inside Person (recursively)
        // effects: Given C-side and S-side Cell Query for a cell, generates
        // the projected slots on both sides corresponding to
        // properties. Also updates the C-side whereclause corresponding to
        // discriminator properties on the C-side, e.g, isHighPriority
        private void ExtractProperties(IEnumerable <StoragePropertyMapping> properties,
                                       MemberPath cNode, List <ProjectedSlot> cSlots,
                                       ref BoolExpression cQueryWhereClause,
                                       MemberPath sRootExtent,
                                       List <ProjectedSlot> sSlots,
                                       ref BoolExpression sQueryWhereClause)
        {
            // For each property mapping, we add an entry to the C and S cell queries
            foreach (StoragePropertyMapping propMap in properties)
            {
                StorageScalarPropertyMapping    scalarPropMap              = propMap as StorageScalarPropertyMapping;
                StorageComplexPropertyMapping   complexPropMap             = propMap as StorageComplexPropertyMapping;
                StorageEndPropertyMapping       associationEndPropertypMap = propMap as StorageEndPropertyMapping;
                StorageConditionPropertyMapping conditionMap = propMap as StorageConditionPropertyMapping;

                Debug.Assert(scalarPropMap != null ||
                             complexPropMap != null ||
                             associationEndPropertypMap != null ||
                             conditionMap != null, "Unimplemented property mapping");

                if (scalarPropMap != null)
                {
                    Debug.Assert(scalarPropMap.ColumnProperty != null, "ColumnMember for a Scalar Property can not be null");
                    // Add an attribute node to node

                    MemberPath cAttributeNode = new MemberPath(cNode, scalarPropMap.EdmProperty);
                    // Add a column (attribute) node the sQuery
                    // unlike the C side, there is no nesting. Hence we
                    // did not need an internal node
                    MemberPath sAttributeNode = new MemberPath(sRootExtent, scalarPropMap.ColumnProperty);
                    cSlots.Add(new MemberProjectedSlot(cAttributeNode));
                    sSlots.Add(new MemberProjectedSlot(sAttributeNode));
                }

                // Note: S-side constants are not allowed since they can cause
                // problems -- for example, if such a cell says 5 for the
                // third field, we cannot guarantee the fact that an
                // application may not set that field to 7 in the C-space

                // Check if the property mapping is for a complex types
                if (complexPropMap != null)
                {
                    foreach (StorageComplexTypeMapping complexTypeMap in complexPropMap.TypeMappings)
                    {
                        // Create a node for the complex type property and call recursively
                        MemberPath complexMemberNode = new MemberPath(cNode, complexPropMap.EdmProperty);
                        //Get the list of types that this type map represents
                        Set <EdmType> allTypes = new Set <EdmType>();
                        // Gather a set of all explicit types for an entity
                        // type mapping in allTypes.
                        IEnumerable <EdmType> exactTypes = Helpers.AsSuperTypeList <ComplexType, EdmType>(complexTypeMap.Types);
                        allTypes.AddRange(exactTypes);
                        foreach (EdmType type in complexTypeMap.IsOfTypes)
                        {
                            allTypes.AddRange(MetadataHelper.GetTypeAndSubtypesOf(type, m_containerMapping.StorageMappingItemCollection.EdmItemCollection, false /*includeAbstractTypes*/));
                        }
                        BoolExpression complexInTypes = BoolExpression.CreateLiteral(new TypeRestriction(complexMemberNode, allTypes), null);
                        cQueryWhereClause = BoolExpression.CreateAnd(cQueryWhereClause, complexInTypes);
                        // Now extract the properties of the complex type
                        // (which could have other complex types)
                        ExtractProperties(complexTypeMap.AllProperties, complexMemberNode, cSlots,
                                          ref cQueryWhereClause, sRootExtent, sSlots, ref sQueryWhereClause);
                    }
                }

                // Check if the property mapping is for an associaion
                if (associationEndPropertypMap != null)
                {
                    // create join tree node representing this relation end
                    MemberPath associationEndNode = new MemberPath(cNode, associationEndPropertypMap.EndMember);
                    // call recursively
                    ExtractProperties(associationEndPropertypMap.Properties, associationEndNode, cSlots,
                                      ref cQueryWhereClause, sRootExtent, sSlots, ref sQueryWhereClause);
                }

                //Check if the this is a condition and add it to the Where clause
                if (conditionMap != null)
                {
                    if (conditionMap.ColumnProperty != null)
                    {
                        //Produce a Condition Expression for the Condition Map.
                        BoolExpression conditionExpression = GetConditionExpression(sRootExtent, conditionMap);
                        //Add the condition expression to the exisiting S side Where clause using an "And"
                        sQueryWhereClause = BoolExpression.CreateAnd(sQueryWhereClause, conditionExpression);
                    }
                    else
                    {
                        Debug.Assert(conditionMap.EdmProperty != null);
                        //Produce a Condition Expression for the Condition Map.
                        BoolExpression conditionExpression = GetConditionExpression(cNode, conditionMap);
                        //Add the condition expression to the exisiting C side Where clause using an "And"
                        cQueryWhereClause = BoolExpression.CreateAnd(cQueryWhereClause, conditionExpression);
                    }
                }
            }
        }