CellCreator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / CellCreator.cs / 2 / CellCreator.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.Data.Common.Utils; 
using System.Data.Mapping.ViewGeneration.Structures;
using System.Collections.Generic;
using System.Data.Mapping.ViewGeneration.Utils;
using System.Diagnostics; 
using System.Data.Metadata.Edm;
 
namespace System.Data.Mapping.ViewGeneration { 

 
    // A class that handles creation of cells from the meta data information
    internal class CellCreator : InternalBase {

        #region Constructors 
        // effects: Creates a cell creator object for an entity container's
        // mappings (specified in "maps") 
        internal CellCreator(StorageEntityContainerMapping containerMapping, MetadataWorkspace workspace) { 
            m_containerMapping = containerMapping;
            m_identifiers = new CqlIdentifiers(); 
            m_workspace = workspace;
        }
        #endregion
 
        #region Fields
        // The mappings from the metadata for different containers 
        private StorageEntityContainerMapping m_containerMapping; 
        private int m_currentCellNumber;
        private MetadataWorkspace m_workspace; 
        private CqlIdentifiers m_identifiers;
        // Keep track of all the identifiers to prevent clashes with _from0,
        // _from1, T, T1, etc
        // Keep track of names of 
        // * Entity Containers
        // * Extent names 
        // * Entity Types 
        // * Complex Types
        // * Properties 
        // * Roles
        #endregion

        #region Properties 
        // effects: Returns the set of identifiers used in this
        internal CqlIdentifiers Identifiers { 
            get { return m_identifiers;} 
        }
        #endregion 

        #region External methods
        // effects: Generates the cells for all the entity containers
        // specified in this. The generated cells are geared for query view generation 
        internal List GenerateCells(ConfigViewGenerator config) {
            List cells = new List(); 
 
            if (config.IsNormalTracing) {
                m_containerMapping.Print(0); 
            }
            // Get the cells from the entity container metadata
            ExtractCellsForContainer(m_containerMapping, cells, m_workspace);
 
            // Get the identifiers from the cells
            m_identifiers.AddIdentifier(m_containerMapping.EdmEntityContainer.Name); 
            m_identifiers.AddIdentifier(m_containerMapping.StorageEntityContainer.Name); 
            foreach (Cell cell in cells) {
                cell.GetIdentifiers(m_identifiers); 
            }

            return cells;
        } 
        #endregion
 
        #region Private Methods 
        // effects: Given the metadata information for a container in
        // containerMap, generate the cells for it and modify cells to 
        // contain the newly-generated cells
        private void ExtractCellsForContainer(StorageEntityContainerMapping containerMap, List cells, MetadataWorkspace workspace) {
            // extract entity mappings, i.e., for CPerson1, COrder1, etc
            foreach (StorageSetMapping extentMap in containerMap.AllSetMaps) { 

                // Get each type map in an entity set mapping, i.e., for 
                // CPerson, CCustomer, etc in CPerson1 
                foreach (StorageTypeMapping typeMap in extentMap.TypeMappings) {
 
                    StorageEntityTypeMapping entityTypeMap = typeMap as StorageEntityTypeMapping;
                    Debug.Assert(entityTypeMap!=null ||
                                 typeMap is StorageAssociationTypeMapping, "Invalid typemap");
 
                    // A set for all the types in this type mapping
                    Set allTypes = new Set(); 
 

                    if (entityTypeMap != null) { 
                        // Gather a set of all explicit types for an entity
                        // type mapping in allTypes. Note that we do not have
                        // subtyping in composition sets and association sets
                        allTypes.AddRange(entityTypeMap.Types); 
                        foreach (EdmType type in entityTypeMap.IsOfTypes) {
                            IEnumerable typeAndSubTypes = MetadataHelper.GetTypeAndSubtypesOf(type, m_workspace, false /*includeAbstractTypes*/); 
                            allTypes.AddRange(typeAndSubTypes); 
                        }
                    } 

                    EntitySetBase extent = extentMap.Set;
                    Debug.Assert(extent != null, "Extent map for a null extent or type of extentMap.Exent " +
                                 "is not Extent"); 

                    // For each table mapping for the type mapping, we create cells 
                    foreach (StorageMappingFragment fragmentMap in typeMap.MappingFragments) { 
                        ExtractCellsFromTableFragment(extent, fragmentMap, allTypes, cells);
                    } 
                }
            }
        }
 
        // effects: Given an extent's ("extent") table fragment that is
        // contained inside typeMap, determine the cells that need to be 
        // created and add them to cells 
        // allTypes corresponds to all the different types that the type map
        // represents -- this parameter has something useful only if extent 
        // is an entity set
        private void ExtractCellsFromTableFragment(EntitySetBase extent, StorageMappingFragment fragmentMap,
                                                   Set allTypes, List cells) {
 
            // create C-query components
            ExtentJoinTreeNode cRootExtentNode = null; 
            // For Composition, the root node of the Join Tree 
            // node has to be the Extent node of the Parent end in the composition
            //set instead of the Composition extent itself. 
            cRootExtentNode = new ExtentJoinTreeNode(extent, new MemberJoinTreeNode[] { }, m_workspace);
            BoolExpression cQueryWhereClause = BoolExpression.True;
            List cSlots = new List();
 
            if (allTypes.Count > 0) {
                // Create a type condition for the extent, i.e., "extent in allTypes" 
                cQueryWhereClause = BoolExpression.CreateLiteral(new OneOfTypeConst(cRootExtentNode, allTypes), null); 
            }
 
            // create S-query components
            ExtentJoinTreeNode sRootExtentNode = new ExtentJoinTreeNode(fragmentMap.TableSet, new MemberJoinTreeNode[] { }, m_workspace);
            BoolExpression sQueryWhereClause = BoolExpression.True;
            List sSlots = new List(); 

            // Association or entity set 
            // Add the properties and the key properties to a list and 
            // then process them in ExtractProperties
            ExtractProperties(fragmentMap.AllProperties, cRootExtentNode, cSlots, ref cQueryWhereClause, sRootExtentNode, sSlots, ref sQueryWhereClause); 

            // limitation of MSL API: cannot assign constant values to table columns
            CellQuery cQuery = new CellQuery(cSlots, cQueryWhereClause, cRootExtentNode);
            CellQuery sQuery = new CellQuery(sSlots, sQueryWhereClause, sRootExtentNode); 
            StorageMappingFragment fragmentInfo = fragmentMap as StorageMappingFragment;
            Debug.Assert((fragmentInfo != null), "CSMappingFragment should support Line Info"); 
            CellLabel label = new CellLabel(fragmentInfo); 
            Cell cell = Cell.CreateCS(cQuery, sQuery, label, m_currentCellNumber);
            m_currentCellNumber++; 
            cells.Add(cell);
        }

        // 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 properties,
                                       JoinTreeNode cNode, List cSlots,
                                       ref BoolExpression cQueryWhereClause, 
                                       JoinTreeNode sRootExtentNode,
                                       List 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
                    JoinTreeNode cAttributeNode = cNode.CreateAttributeNode(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 
                    JoinTreeNode sAttributeNode = sRootExtentNode.CreateAttributeNode(scalarPropMap.ColumnProperty);
                    cSlots.Add(new JoinTreeSlot(cAttributeNode));
                    sSlots.Add(new JoinTreeSlot(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 an complex types
                if (complexPropMap != null) {
                    foreach (StorageComplexTypeMapping complexTypeMap in complexPropMap.TypeMappings) {
                        // Create a node for the complex type property and call recursively 
                        JoinTreeNode complexMemberNode = cNode.CreateAttributeNode(complexPropMap.EdmProperty);
                        //Get the list of types that this type map represents 
                        Set allTypes = new Set(); 
                        // Gather a set of all explicit types for an entity
                        // type mapping in allTypes. 
                        IEnumerable exactTypes = Helpers.AsSuperTypeList(complexTypeMap.Types);
                        allTypes.AddRange(exactTypes);
                        foreach (EdmType type in complexTypeMap.IsOfTypes) {
                            allTypes.AddRange(MetadataHelper.GetTypeAndSubtypesOf(type, m_workspace, false /*includeAbstractTypes*/)); 
                        }
                        BoolExpression complexInTypes = BoolExpression.CreateLiteral(new OneOfTypeConst(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, sRootExtentNode, sSlots, ref sQueryWhereClause);
                    }
                } 

                // Check if the property mapping is for an associaion 
                if (associationEndPropertypMap != null) { 
                    // create join tree node representing this relation end
                        JoinTreeNode associationEndNode = cNode.CreateAttributeNode(associationEndPropertypMap.EndMember); 
                    // call recursively
                    ExtractProperties(associationEndPropertypMap.Properties, associationEndNode, cSlots,
                                      ref cQueryWhereClause, sRootExtentNode, 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(sRootExtentNode, 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);
                    }

                } 
            }
        } 
 
        /// 
        /// Takes in a JoinTreeNode and a Contition Property Map and creates an BoolExpression 
        /// for the Condition Map.
        /// 
        /// 
        ///  
        /// 
        private static BoolExpression GetConditionExpression(JoinTreeNode joinTreeNode, StorageConditionPropertyMapping conditionMap) { 
            //Get the member for which the condition is being specified 
            EdmMember conditionMember = (conditionMap.ColumnProperty != null) ? conditionMap.ColumnProperty : conditionMap.EdmProperty;
            JoinTreeNode conditionMemberNode = joinTreeNode.CreateAttributeNode(conditionMember); 
            //Check if this is a IsNull condition
            OneOfConst conditionExpression = null;
            if (conditionMap.IsNull.HasValue) {
                // for conditions on scalars, create NodeValue nodes, otherwise NodeType 
                CellConstant conditionConstant = (true == conditionMap.IsNull.Value) ? CellConstant.Null : CellConstant.NotNull;
                if (true == MetadataHelper.IsNonRefSimpleMember(conditionMember)) { 
                    conditionExpression = new OneOfScalarConst(conditionMemberNode, conditionConstant); 
                } else {
                    conditionExpression = new OneOfTypeConst(conditionMemberNode, conditionConstant); 
                }
            }
            else {
                TypeUsage conditionMemberTypeUsage = (conditionMap.ColumnProperty != null) ? conditionMap.ColumnProperty.TypeUsage : conditionMap.EdmProperty.TypeUsage; 
                conditionExpression = new OneOfScalarConst(conditionMemberNode, conditionMap.Value, conditionMemberTypeUsage);
            } 
 
            Debug.Assert(conditionExpression != null);
 
            return BoolExpression.CreateLiteral(conditionExpression, null);
        }
        #endregion
 
        #region String methods
        internal override void ToCompactString(System.Text.StringBuilder builder) { 
            builder.Append("CellCreator"); // No state to really show i.e., m_maps 
        }
 
        #endregion

    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.Data.Common.Utils; 
using System.Data.Mapping.ViewGeneration.Structures;
using System.Collections.Generic;
using System.Data.Mapping.ViewGeneration.Utils;
using System.Diagnostics; 
using System.Data.Metadata.Edm;
 
namespace System.Data.Mapping.ViewGeneration { 

 
    // A class that handles creation of cells from the meta data information
    internal class CellCreator : InternalBase {

        #region Constructors 
        // effects: Creates a cell creator object for an entity container's
        // mappings (specified in "maps") 
        internal CellCreator(StorageEntityContainerMapping containerMapping, MetadataWorkspace workspace) { 
            m_containerMapping = containerMapping;
            m_identifiers = new CqlIdentifiers(); 
            m_workspace = workspace;
        }
        #endregion
 
        #region Fields
        // The mappings from the metadata for different containers 
        private StorageEntityContainerMapping m_containerMapping; 
        private int m_currentCellNumber;
        private MetadataWorkspace m_workspace; 
        private CqlIdentifiers m_identifiers;
        // Keep track of all the identifiers to prevent clashes with _from0,
        // _from1, T, T1, etc
        // Keep track of names of 
        // * Entity Containers
        // * Extent names 
        // * Entity Types 
        // * Complex Types
        // * Properties 
        // * Roles
        #endregion

        #region Properties 
        // effects: Returns the set of identifiers used in this
        internal CqlIdentifiers Identifiers { 
            get { return m_identifiers;} 
        }
        #endregion 

        #region External methods
        // effects: Generates the cells for all the entity containers
        // specified in this. The generated cells are geared for query view generation 
        internal List GenerateCells(ConfigViewGenerator config) {
            List cells = new List(); 
 
            if (config.IsNormalTracing) {
                m_containerMapping.Print(0); 
            }
            // Get the cells from the entity container metadata
            ExtractCellsForContainer(m_containerMapping, cells, m_workspace);
 
            // Get the identifiers from the cells
            m_identifiers.AddIdentifier(m_containerMapping.EdmEntityContainer.Name); 
            m_identifiers.AddIdentifier(m_containerMapping.StorageEntityContainer.Name); 
            foreach (Cell cell in cells) {
                cell.GetIdentifiers(m_identifiers); 
            }

            return cells;
        } 
        #endregion
 
        #region Private Methods 
        // effects: Given the metadata information for a container in
        // containerMap, generate the cells for it and modify cells to 
        // contain the newly-generated cells
        private void ExtractCellsForContainer(StorageEntityContainerMapping containerMap, List cells, MetadataWorkspace workspace) {
            // extract entity mappings, i.e., for CPerson1, COrder1, etc
            foreach (StorageSetMapping extentMap in containerMap.AllSetMaps) { 

                // Get each type map in an entity set mapping, i.e., for 
                // CPerson, CCustomer, etc in CPerson1 
                foreach (StorageTypeMapping typeMap in extentMap.TypeMappings) {
 
                    StorageEntityTypeMapping entityTypeMap = typeMap as StorageEntityTypeMapping;
                    Debug.Assert(entityTypeMap!=null ||
                                 typeMap is StorageAssociationTypeMapping, "Invalid typemap");
 
                    // A set for all the types in this type mapping
                    Set allTypes = new Set(); 
 

                    if (entityTypeMap != null) { 
                        // Gather a set of all explicit types for an entity
                        // type mapping in allTypes. Note that we do not have
                        // subtyping in composition sets and association sets
                        allTypes.AddRange(entityTypeMap.Types); 
                        foreach (EdmType type in entityTypeMap.IsOfTypes) {
                            IEnumerable typeAndSubTypes = MetadataHelper.GetTypeAndSubtypesOf(type, m_workspace, false /*includeAbstractTypes*/); 
                            allTypes.AddRange(typeAndSubTypes); 
                        }
                    } 

                    EntitySetBase extent = extentMap.Set;
                    Debug.Assert(extent != null, "Extent map for a null extent or type of extentMap.Exent " +
                                 "is not Extent"); 

                    // For each table mapping for the type mapping, we create cells 
                    foreach (StorageMappingFragment fragmentMap in typeMap.MappingFragments) { 
                        ExtractCellsFromTableFragment(extent, fragmentMap, allTypes, cells);
                    } 
                }
            }
        }
 
        // effects: Given an extent's ("extent") table fragment that is
        // contained inside typeMap, determine the cells that need to be 
        // created and add them to cells 
        // allTypes corresponds to all the different types that the type map
        // represents -- this parameter has something useful only if extent 
        // is an entity set
        private void ExtractCellsFromTableFragment(EntitySetBase extent, StorageMappingFragment fragmentMap,
                                                   Set allTypes, List cells) {
 
            // create C-query components
            ExtentJoinTreeNode cRootExtentNode = null; 
            // For Composition, the root node of the Join Tree 
            // node has to be the Extent node of the Parent end in the composition
            //set instead of the Composition extent itself. 
            cRootExtentNode = new ExtentJoinTreeNode(extent, new MemberJoinTreeNode[] { }, m_workspace);
            BoolExpression cQueryWhereClause = BoolExpression.True;
            List cSlots = new List();
 
            if (allTypes.Count > 0) {
                // Create a type condition for the extent, i.e., "extent in allTypes" 
                cQueryWhereClause = BoolExpression.CreateLiteral(new OneOfTypeConst(cRootExtentNode, allTypes), null); 
            }
 
            // create S-query components
            ExtentJoinTreeNode sRootExtentNode = new ExtentJoinTreeNode(fragmentMap.TableSet, new MemberJoinTreeNode[] { }, m_workspace);
            BoolExpression sQueryWhereClause = BoolExpression.True;
            List sSlots = new List(); 

            // Association or entity set 
            // Add the properties and the key properties to a list and 
            // then process them in ExtractProperties
            ExtractProperties(fragmentMap.AllProperties, cRootExtentNode, cSlots, ref cQueryWhereClause, sRootExtentNode, sSlots, ref sQueryWhereClause); 

            // limitation of MSL API: cannot assign constant values to table columns
            CellQuery cQuery = new CellQuery(cSlots, cQueryWhereClause, cRootExtentNode);
            CellQuery sQuery = new CellQuery(sSlots, sQueryWhereClause, sRootExtentNode); 
            StorageMappingFragment fragmentInfo = fragmentMap as StorageMappingFragment;
            Debug.Assert((fragmentInfo != null), "CSMappingFragment should support Line Info"); 
            CellLabel label = new CellLabel(fragmentInfo); 
            Cell cell = Cell.CreateCS(cQuery, sQuery, label, m_currentCellNumber);
            m_currentCellNumber++; 
            cells.Add(cell);
        }

        // 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 properties,
                                       JoinTreeNode cNode, List cSlots,
                                       ref BoolExpression cQueryWhereClause, 
                                       JoinTreeNode sRootExtentNode,
                                       List 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
                    JoinTreeNode cAttributeNode = cNode.CreateAttributeNode(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 
                    JoinTreeNode sAttributeNode = sRootExtentNode.CreateAttributeNode(scalarPropMap.ColumnProperty);
                    cSlots.Add(new JoinTreeSlot(cAttributeNode));
                    sSlots.Add(new JoinTreeSlot(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 an complex types
                if (complexPropMap != null) {
                    foreach (StorageComplexTypeMapping complexTypeMap in complexPropMap.TypeMappings) {
                        // Create a node for the complex type property and call recursively 
                        JoinTreeNode complexMemberNode = cNode.CreateAttributeNode(complexPropMap.EdmProperty);
                        //Get the list of types that this type map represents 
                        Set allTypes = new Set(); 
                        // Gather a set of all explicit types for an entity
                        // type mapping in allTypes. 
                        IEnumerable exactTypes = Helpers.AsSuperTypeList(complexTypeMap.Types);
                        allTypes.AddRange(exactTypes);
                        foreach (EdmType type in complexTypeMap.IsOfTypes) {
                            allTypes.AddRange(MetadataHelper.GetTypeAndSubtypesOf(type, m_workspace, false /*includeAbstractTypes*/)); 
                        }
                        BoolExpression complexInTypes = BoolExpression.CreateLiteral(new OneOfTypeConst(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, sRootExtentNode, sSlots, ref sQueryWhereClause);
                    }
                } 

                // Check if the property mapping is for an associaion 
                if (associationEndPropertypMap != null) { 
                    // create join tree node representing this relation end
                        JoinTreeNode associationEndNode = cNode.CreateAttributeNode(associationEndPropertypMap.EndMember); 
                    // call recursively
                    ExtractProperties(associationEndPropertypMap.Properties, associationEndNode, cSlots,
                                      ref cQueryWhereClause, sRootExtentNode, 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(sRootExtentNode, 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);
                    }

                } 
            }
        } 
 
        /// 
        /// Takes in a JoinTreeNode and a Contition Property Map and creates an BoolExpression 
        /// for the Condition Map.
        /// 
        /// 
        ///  
        /// 
        private static BoolExpression GetConditionExpression(JoinTreeNode joinTreeNode, StorageConditionPropertyMapping conditionMap) { 
            //Get the member for which the condition is being specified 
            EdmMember conditionMember = (conditionMap.ColumnProperty != null) ? conditionMap.ColumnProperty : conditionMap.EdmProperty;
            JoinTreeNode conditionMemberNode = joinTreeNode.CreateAttributeNode(conditionMember); 
            //Check if this is a IsNull condition
            OneOfConst conditionExpression = null;
            if (conditionMap.IsNull.HasValue) {
                // for conditions on scalars, create NodeValue nodes, otherwise NodeType 
                CellConstant conditionConstant = (true == conditionMap.IsNull.Value) ? CellConstant.Null : CellConstant.NotNull;
                if (true == MetadataHelper.IsNonRefSimpleMember(conditionMember)) { 
                    conditionExpression = new OneOfScalarConst(conditionMemberNode, conditionConstant); 
                } else {
                    conditionExpression = new OneOfTypeConst(conditionMemberNode, conditionConstant); 
                }
            }
            else {
                TypeUsage conditionMemberTypeUsage = (conditionMap.ColumnProperty != null) ? conditionMap.ColumnProperty.TypeUsage : conditionMap.EdmProperty.TypeUsage; 
                conditionExpression = new OneOfScalarConst(conditionMemberNode, conditionMap.Value, conditionMemberTypeUsage);
            } 
 
            Debug.Assert(conditionExpression != null);
 
            return BoolExpression.CreateLiteral(conditionExpression, null);
        }
        #endregion
 
        #region String methods
        internal override void ToCompactString(System.Text.StringBuilder builder) { 
            builder.Append("CellCreator"); // No state to really show i.e., m_maps 
        }
 
        #endregion

    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK