StorageEntityContainerMapping.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 / Mapping / StorageEntityContainerMapping.cs / 4 / StorageEntityContainerMapping.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  	 [....], [....]
//--------------------------------------------------------------------- 
using System; 
using System.Collections.Generic;
using System.Collections.ObjectModel; 
using System.Linq;
using System.Text;
using System.Xml;
using System.Data.Metadata.Edm; 
using System.Diagnostics;
using System.Data.Mapping.ViewGeneration; 
using System.Data.Common.Utils; 
using System.Data.Mapping.ViewGeneration.Structures;
using System.Data.Mapping.ViewGeneration.Validation; 

namespace System.Data.Mapping {

    using CellGroup = Set; 

    ///  
    /// Represents the Mapping metadata for the EntityContainer map in ES space. 
    /// EntityContainerMapping is the only top level construct that is allowed in the MSL file
    /// for ESMapping. 
    /// 
    /// For Example if conceptually you could represent the CS MSL file as following
    /// ---Mapping
    ///    --EntityContainerMapping ( CNorthwind-->SNorthwind ) 
    ///      --EntitySetMapping
    ///        --AssociationSetMapping 
    ///    --EntityContainerMapping ( CMyDatabase-->SMyDatabase ) 
    ///      --CompositionSetMapping
    /// The type represents the metadata for EntityContainerMapping element in the above example. 
    /// The SetMapping elements that are children of the EntityContainerMapping element
    /// can be accessed through the properties on this type.
    /// 
    ///  
    /// We currently assume that an Entity Container on the C side
    /// is mapped to a single Entity Container in the S - space. 
    ///  
    /// 
    internal class StorageEntityContainerMapping : Map 
 {
        #region Constructors
        /// 
        /// Construct a new EntityContainer mapping object 
        /// passing in the E-space EntityContainer  and
        /// the s-space Entity container metadata objects. 
        ///  
        /// Entity Continer type that is being mapped on the E-side
        /// Entity Continer type that is being mapped on the S-side 
        internal StorageEntityContainerMapping(EntityContainer entityContainer, EntityContainer storageEntityContainer, StorageMappingItemCollection storageMappingItemCollection) {
            this.m_entityContainer = entityContainer;
            this.m_storageEntityContainer = storageEntityContainer;
            this.m_storageMappingItemCollection = storageMappingItemCollection; 
            this.m_memoizedCellGroupEvaluator = new Memoizer(ComputeCellGroups, new InputForComputingCellGroups());
            this.identity = entityContainer.Identity; 
        } 
        #endregion
 
        #region Fields
        private string identity;
        private EntityContainer m_entityContainer;  //Entity Continer type that is being mapped on the C-side
        private EntityContainer m_storageEntityContainer;  //Entity Continer type that the C-space container is being mapped to 
        private Dictionary m_entitySetMappings = new Dictionary(StringComparer.Ordinal);  //A collection of EntitySetMappings under this EntityContainer mapping
        private Dictionary m_associationSetMappings = new Dictionary(StringComparer.Ordinal);  //A collection of AssociationSetMappings under this EntityContainer mapping 
        private Dictionary m_functionImportMappings = new Dictionary(); 
        private string m_sourceLocation; //Schema URI for the mapping
        private int m_startLineNumber; //Line Number for EntityContainer Mapping element start tag 
        private int m_startLinePosition; //Line position for EntityContainer Mapping element start tag
        private readonly StorageMappingItemCollection m_storageMappingItemCollection;
        private readonly Memoizer m_memoizedCellGroupEvaluator;
 
        #endregion
 
        #region Properties 

        public StorageMappingItemCollection StorageMappingItemCollection 
        {
            get
            {
                return m_storageMappingItemCollection; 
            }
        } 
 
        /// 
        /// Gets the type kind for this item 
        /// 
        public override BuiltInTypeKind BuiltInTypeKind {
            get { return BuiltInTypeKind.MetadataItem; }
        } 

        ///  
        /// The Entity Container Metadata object on the E-side 
        /// for which the mapping is being represented.
        ///  
        internal override MetadataItem EdmItem {
            get {
                return this.m_entityContainer;
            } 
        }
 
        ///  
        /// Returns the Identity of ObjectTypeMapping.
        /// The identity for an Object Type Map is the concatenation of 
        /// CLR Type Idntity + ':' + CDM Type Identity
        /// 
        internal override string Identity {
            get { 
                return identity;
            } 
        } 

        ///  
        /// Indicates whether there are no Set mappings
        /// in the container mapping.
        /// 
        internal bool IsEmpty 
        {
            get 
            { 
                return ((m_entitySetMappings.Count == 0)
                && (m_associationSetMappings.Count == 0)); 
            }
        }

        internal string SourceLocation { 
            get { return m_sourceLocation; }
            set { m_sourceLocation = value; } 
        } 

        ///  
        /// The Entity Container Metadata object on the E-side
        /// for which the mapping is being represented.
        /// 
        internal EntityContainer EdmEntityContainer { 
            get {
                return this.m_entityContainer; 
            } 
        }
 
        /// 
        /// The Entity Container Metadata object on the C-side
        /// for which the mapping is being represented.
        ///  
        internal EntityContainer StorageEntityContainer {
            get { 
                return this.m_storageEntityContainer; 
            }
        } 

        /// 
        /// a list of all the  entity set maps under this
        /// container. In CS mapping, the mapping is done 
        /// at the extent level as opposed to the type level.
        ///  
        internal ReadOnlyCollection EntitySetMaps { 
            get {
                return new List(this.m_entitySetMappings.Values).AsReadOnly(); 
            }
        }

        ///  
        /// a list of all the  entity set maps under this
        /// container. In CS mapping, the mapping is done 
        /// at the extent level as opposed to the type level. 
        /// RelationshipSetMaps will be CompositionSetMaps and
        /// AssociationSetMaps put together. 
        /// 
        /// 
        /// The reason we have RelationshipSetMaps is to be consistent with CDM metadata
        /// which treats both associations and compositions as Relationships. 
        /// 
        internal ReadOnlyCollection RelationshipSetMaps { 
            get { 
                return new List(this.m_associationSetMappings.Values).AsReadOnly();
            } 
        }

        /// 
        /// a list of all the  set maps under this 
        /// container.
        ///  
        internal IEnumerable AllSetMaps 
        {
            get 
            {
                return System.Linq.Enumerable.Concat(this.m_entitySetMappings.Values, this.m_associationSetMappings.Values);
            }
        } 

        ///  
        /// Line Number in MSL file where the EntityContainer Mapping Element's Start Tag is present. 
        /// 
        internal int StartLineNumber 
        {
            get
            {
                return m_startLineNumber; 
            }
            set 
            { 
                m_startLineNumber = value;
            } 
        }

        /// 
        /// Line Position in MSL file where the EntityContainer Mapping Element's Start Tag is present. 
        /// 
        internal int StartLinePosition 
        { 
            get
            { 
                return m_startLinePosition;
            }
            set
            { 
                m_startLinePosition = value;
            } 
        } 

 
        #endregion

        #region Methods
        ///  
        /// get an EntitySet mapping based upon the name of the entity set.
        ///  
        /// /// the name of the entity set 
        internal StorageSetMapping GetEntitySetMapping(String entitySetName) {
            EntityUtil.CheckArgumentNull(entitySetName, "entitySetName"); 
            //Key for EntitySetMapping should be EntitySet name and Entoty type name
            StorageSetMapping setMapping = null;
            m_entitySetMappings.TryGetValue(entitySetName, out setMapping);
            return setMapping; 
        }
 
        ///  
        /// Get a RelationShip set mapping based upon the name of the relationship set
        ///  
        /// the name of the relationship set
        /// the mapping for the entity set if it exists, null if it does not exist
        internal StorageSetMapping GetRelationshipSetMapping(string relationshipSetName) {
            EntityUtil.CheckArgumentNull(relationshipSetName, "relationshipSetName"); 
            StorageSetMapping setMapping = null;
            m_associationSetMappings.TryGetValue(relationshipSetName, out setMapping); 
            return setMapping; 
        }
 
        /// 
        /// Get a RelationShipSet mapping that has the passed in EntitySet as one of the ends and is mapped to the
        /// table.
        ///  
        internal IEnumerable GetRelationshipSetMappingsFor(EntitySetBase edmEntitySet, EntitySetBase storeEntitySet )
        { 
            //First select the association set maps that are mapped to this table 
            IEnumerable associationSetMappings = m_associationSetMappings.Values.Cast().Where(w => ((w.StoreEntitySet != null) && (w.StoreEntitySet == storeEntitySet)));
            //From this again filter the ones that have the specified EntitySet on atleast one end 
            associationSetMappings = associationSetMappings.Where(associationSetMap => ((associationSetMap.Set as AssociationSet).AssociationSetEnds.Any(associationSetEnd => associationSetEnd.EntitySet == edmEntitySet)));
            return associationSetMappings;
        }
 

        ///  
        /// Get a set mapping based upon the name of the set 
        /// 
        ///  
        /// 
        internal StorageSetMapping GetSetMapping(string setName)
        {
            StorageSetMapping setMap = GetEntitySetMapping(setName); 
            if (setMap == null)
            { 
                setMap = GetRelationshipSetMapping(setName); 
            }
            return setMap; 
        }


        ///  
        /// Adds an entity set mapping to the list of EntitySetMaps
        /// under this entity container mapping. The method will be called 
        /// by the Mapping loader. 
        /// 
        internal void AddEntitySetMapping(StorageSetMapping setMapping) { 
            if (!this.m_entitySetMappings.ContainsKey(setMapping.Set.Name))
                this.m_entitySetMappings.Add(setMapping.Set.Name, setMapping);
        }
 
        /// 
        /// Adds a association set mapping to the list of AssociationSetMaps 
        /// under this entity container mapping. The method will be called 
        /// by the Mapping loader.
        ///  
        internal void AddAssociationSetMapping(StorageSetMapping setMapping) {
            this.m_associationSetMappings.Add(setMapping.Set.Name, setMapping);
        }
 
        /// 
        /// check whether the EntityContainerMapping contains 
        /// the map for the given AssociationSet 
        /// 
        ///  
        /// 
        internal bool ContainsAssociationSetMapping(AssociationSet associationSet) {
            return this.m_associationSetMappings.ContainsKey(associationSet.Name);
        } 

        ///  
        /// Returns whether the Set Map for the given set has a query view or not 
        /// 
        ///  
        /// 
        internal bool HasQueryViewForSetMap(string setName)
        {
            StorageSetMapping set = GetSetMapping(setName); 
            if (set != null)
            { 
                return (set.QueryView != null); 
            }
            return false; 
        }


        /// 
        /// The method builds up the spaces required for pretty printing each
        /// part of the mapping. 
        /// 
        internal static string GetPrettyPrintString(ref int index) {
 
            string spaces = "";
            spaces = spaces.PadLeft(index, ' ');
            Console.WriteLine(spaces + "|");
            Console.WriteLine(spaces + "|"); 
            index++;
            spaces = spaces.PadLeft(index, ' '); 
            Console.Write(spaces + "-"); 
            index++;
            spaces = spaces.PadLeft(index, ' '); 
            Console.Write("-");
            index++;
            spaces = spaces.PadLeft(index, ' ');
            return spaces; 
        }
 
 
        /// 
        /// This method is primarily for debugging purposes. 
        /// Will be removed shortly.
        /// 
        /// 
        internal void Print(int index) { 
            string spaces = "";
            StringBuilder sb = new StringBuilder(); 
            sb.Append(spaces); 
            sb.Append("EntityContainerMapping");
            sb.Append("   "); 
            sb.Append("Name:");
            sb.Append(this.m_entityContainer.Name);
            sb.Append("   ");
            Console.WriteLine(sb.ToString()); 
            foreach (StorageSetMapping extentMapping in m_entitySetMappings.Values) {
                extentMapping.Print(index + 5); 
            } 
            foreach (StorageSetMapping extentMapping in m_associationSetMappings.Values) {
                extentMapping.Print(index + 5); 
            }
        }

 
        // Methods to modify and access function imports, which association a "functionImport" declared
        // in the model entity container with a targetFunction declared in the target 
        internal void AddFunctionImportMapping(EdmFunction functionImport, FunctionImportMapping targetFunction) 
        {
            m_functionImportMappings.Add(functionImport, targetFunction); 
        }

        internal bool TryGetFunctionImportMapping(EdmFunction functionImport, out FunctionImportMapping targetFunction)
        { 
            return m_functionImportMappings.TryGetValue(functionImport, out targetFunction);
        } 
 
        internal OutputFromComputeCellGroups GetCellgroups(InputForComputingCellGroups args)
        { 
            Debug.Assert(object.ReferenceEquals(this, args.ContainerMapping));
            return m_memoizedCellGroupEvaluator.Evaluate(args);
        }
 
        private OutputFromComputeCellGroups ComputeCellGroups(InputForComputingCellGroups args)
        { 
            OutputFromComputeCellGroups result = new OutputFromComputeCellGroups(); 
            result.Success = true;
 
            //Don't want to cache on workspace because workspace may change
            MetadataWorkspace workspace = new MetadataWorkspace();
            workspace.RegisterItemCollection(args.ContainerMapping.StorageMappingItemCollection.EdmItemCollection);
            workspace.RegisterItemCollection(args.ContainerMapping.StorageMappingItemCollection.StoreItemCollection); 
            workspace.RegisterItemCollection(args.ContainerMapping.StorageMappingItemCollection);
 
            CellCreator cellCreator = new CellCreator(args.ContainerMapping, workspace); 
            result.Cells = cellCreator.GenerateCells(args.Config);
            result.Identifiers = cellCreator.Identifiers; 

            if (result.Cells.Count <= 0)
            {
                //When type-specific QVs are asked for but not defined in the MSL we should return without generating 
                // Query pipeline will handle this appropriately by asking for UNION ALL view.
                result.Success = false; 
                return result; 
            }
 
            result.ForeignKeyConstraints = ForeignConstraint.GetForeignConstraints(args.ContainerMapping.StorageEntityContainer, workspace);

            // Go through each table and determine their foreign key constraints
            CellPartitioner partitioner = new CellPartitioner(result.Cells, result.ForeignKeyConstraints); 
            List cellGroups = partitioner.GroupRelatedCells();
 
            //Clone cell groups- i.e, List> - upto cell before storing it in the cache because viewgen modified the Cell structure 
            result.CellGroups = cellGroups.Select(setOfcells => new CellGroup(setOfcells.Select(cell => new Cell(cell)))).ToList();
 
            return result;
        }

        #endregion 
    }
 
    internal struct InputForComputingCellGroups : IEquatable, IEqualityComparer 
    {
        internal readonly StorageEntityContainerMapping ContainerMapping; 
        internal readonly ConfigViewGenerator Config;

        internal InputForComputingCellGroups(StorageEntityContainerMapping containerMapping, ConfigViewGenerator config)
        { 
            this.ContainerMapping = containerMapping;
            this.Config = config; 
        } 

        public bool Equals(InputForComputingCellGroups other) 
        {
            // Isn't this funny? We are not using Memoizer for function memoization. Args Entity and Config don't matter!
            // If I were to compare Entity this would not use the cache for cases when I supply different entity set. However,
            // the cell groups belong to ALL entity sets. 
            return (this.ContainerMapping.Equals(other.ContainerMapping)
                && this.Config.Equals(other.Config)); 
        } 

        public bool Equals(InputForComputingCellGroups one, InputForComputingCellGroups two) 
        {
            if (object.ReferenceEquals(one, two))
            {
                return true; 
            }
            if (object.ReferenceEquals(one, null) || object.ReferenceEquals(two, null)) 
            { 
                return false;
            } 

            return one.Equals(two);
        }
 
        public int GetHashCode(InputForComputingCellGroups value)
        { 
            if (value == null) 
            {
                return 0; 
            }

            return value.GetHashCode();
        } 

        public override int GetHashCode() 
        { 
            return this.ContainerMapping.GetHashCode();
        } 

        public override bool Equals(object obj)
        {
            if (obj is InputForComputingCellGroups) 
            {
                return Equals((InputForComputingCellGroups)obj); 
            } 
            else
            { 
                return false;
            }
        }
 
        public static bool operator ==(InputForComputingCellGroups input1, InputForComputingCellGroups input2)
        { 
            if (object.ReferenceEquals(input1, input2)) 
            {
                return true; 
            }
            return input1.Equals(input2);
        }
 
        public static bool operator !=(InputForComputingCellGroups input1, InputForComputingCellGroups input2)
        { 
            return !(input1 == input2); 
        }
 
    }

    internal struct OutputFromComputeCellGroups
    { 
        internal List Cells;
        internal CqlIdentifiers Identifiers; 
        internal List CellGroups; 
        internal List ForeignKeyConstraints;
        internal bool Success; 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  	 [....], [....]
//--------------------------------------------------------------------- 
using System; 
using System.Collections.Generic;
using System.Collections.ObjectModel; 
using System.Linq;
using System.Text;
using System.Xml;
using System.Data.Metadata.Edm; 
using System.Diagnostics;
using System.Data.Mapping.ViewGeneration; 
using System.Data.Common.Utils; 
using System.Data.Mapping.ViewGeneration.Structures;
using System.Data.Mapping.ViewGeneration.Validation; 

namespace System.Data.Mapping {

    using CellGroup = Set; 

    ///  
    /// Represents the Mapping metadata for the EntityContainer map in ES space. 
    /// EntityContainerMapping is the only top level construct that is allowed in the MSL file
    /// for ESMapping. 
    /// 
    /// For Example if conceptually you could represent the CS MSL file as following
    /// ---Mapping
    ///    --EntityContainerMapping ( CNorthwind-->SNorthwind ) 
    ///      --EntitySetMapping
    ///        --AssociationSetMapping 
    ///    --EntityContainerMapping ( CMyDatabase-->SMyDatabase ) 
    ///      --CompositionSetMapping
    /// The type represents the metadata for EntityContainerMapping element in the above example. 
    /// The SetMapping elements that are children of the EntityContainerMapping element
    /// can be accessed through the properties on this type.
    /// 
    ///  
    /// We currently assume that an Entity Container on the C side
    /// is mapped to a single Entity Container in the S - space. 
    ///  
    /// 
    internal class StorageEntityContainerMapping : Map 
 {
        #region Constructors
        /// 
        /// Construct a new EntityContainer mapping object 
        /// passing in the E-space EntityContainer  and
        /// the s-space Entity container metadata objects. 
        ///  
        /// Entity Continer type that is being mapped on the E-side
        /// Entity Continer type that is being mapped on the S-side 
        internal StorageEntityContainerMapping(EntityContainer entityContainer, EntityContainer storageEntityContainer, StorageMappingItemCollection storageMappingItemCollection) {
            this.m_entityContainer = entityContainer;
            this.m_storageEntityContainer = storageEntityContainer;
            this.m_storageMappingItemCollection = storageMappingItemCollection; 
            this.m_memoizedCellGroupEvaluator = new Memoizer(ComputeCellGroups, new InputForComputingCellGroups());
            this.identity = entityContainer.Identity; 
        } 
        #endregion
 
        #region Fields
        private string identity;
        private EntityContainer m_entityContainer;  //Entity Continer type that is being mapped on the C-side
        private EntityContainer m_storageEntityContainer;  //Entity Continer type that the C-space container is being mapped to 
        private Dictionary m_entitySetMappings = new Dictionary(StringComparer.Ordinal);  //A collection of EntitySetMappings under this EntityContainer mapping
        private Dictionary m_associationSetMappings = new Dictionary(StringComparer.Ordinal);  //A collection of AssociationSetMappings under this EntityContainer mapping 
        private Dictionary m_functionImportMappings = new Dictionary(); 
        private string m_sourceLocation; //Schema URI for the mapping
        private int m_startLineNumber; //Line Number for EntityContainer Mapping element start tag 
        private int m_startLinePosition; //Line position for EntityContainer Mapping element start tag
        private readonly StorageMappingItemCollection m_storageMappingItemCollection;
        private readonly Memoizer m_memoizedCellGroupEvaluator;
 
        #endregion
 
        #region Properties 

        public StorageMappingItemCollection StorageMappingItemCollection 
        {
            get
            {
                return m_storageMappingItemCollection; 
            }
        } 
 
        /// 
        /// Gets the type kind for this item 
        /// 
        public override BuiltInTypeKind BuiltInTypeKind {
            get { return BuiltInTypeKind.MetadataItem; }
        } 

        ///  
        /// The Entity Container Metadata object on the E-side 
        /// for which the mapping is being represented.
        ///  
        internal override MetadataItem EdmItem {
            get {
                return this.m_entityContainer;
            } 
        }
 
        ///  
        /// Returns the Identity of ObjectTypeMapping.
        /// The identity for an Object Type Map is the concatenation of 
        /// CLR Type Idntity + ':' + CDM Type Identity
        /// 
        internal override string Identity {
            get { 
                return identity;
            } 
        } 

        ///  
        /// Indicates whether there are no Set mappings
        /// in the container mapping.
        /// 
        internal bool IsEmpty 
        {
            get 
            { 
                return ((m_entitySetMappings.Count == 0)
                && (m_associationSetMappings.Count == 0)); 
            }
        }

        internal string SourceLocation { 
            get { return m_sourceLocation; }
            set { m_sourceLocation = value; } 
        } 

        ///  
        /// The Entity Container Metadata object on the E-side
        /// for which the mapping is being represented.
        /// 
        internal EntityContainer EdmEntityContainer { 
            get {
                return this.m_entityContainer; 
            } 
        }
 
        /// 
        /// The Entity Container Metadata object on the C-side
        /// for which the mapping is being represented.
        ///  
        internal EntityContainer StorageEntityContainer {
            get { 
                return this.m_storageEntityContainer; 
            }
        } 

        /// 
        /// a list of all the  entity set maps under this
        /// container. In CS mapping, the mapping is done 
        /// at the extent level as opposed to the type level.
        ///  
        internal ReadOnlyCollection EntitySetMaps { 
            get {
                return new List(this.m_entitySetMappings.Values).AsReadOnly(); 
            }
        }

        ///  
        /// a list of all the  entity set maps under this
        /// container. In CS mapping, the mapping is done 
        /// at the extent level as opposed to the type level. 
        /// RelationshipSetMaps will be CompositionSetMaps and
        /// AssociationSetMaps put together. 
        /// 
        /// 
        /// The reason we have RelationshipSetMaps is to be consistent with CDM metadata
        /// which treats both associations and compositions as Relationships. 
        /// 
        internal ReadOnlyCollection RelationshipSetMaps { 
            get { 
                return new List(this.m_associationSetMappings.Values).AsReadOnly();
            } 
        }

        /// 
        /// a list of all the  set maps under this 
        /// container.
        ///  
        internal IEnumerable AllSetMaps 
        {
            get 
            {
                return System.Linq.Enumerable.Concat(this.m_entitySetMappings.Values, this.m_associationSetMappings.Values);
            }
        } 

        ///  
        /// Line Number in MSL file where the EntityContainer Mapping Element's Start Tag is present. 
        /// 
        internal int StartLineNumber 
        {
            get
            {
                return m_startLineNumber; 
            }
            set 
            { 
                m_startLineNumber = value;
            } 
        }

        /// 
        /// Line Position in MSL file where the EntityContainer Mapping Element's Start Tag is present. 
        /// 
        internal int StartLinePosition 
        { 
            get
            { 
                return m_startLinePosition;
            }
            set
            { 
                m_startLinePosition = value;
            } 
        } 

 
        #endregion

        #region Methods
        ///  
        /// get an EntitySet mapping based upon the name of the entity set.
        ///  
        /// /// the name of the entity set 
        internal StorageSetMapping GetEntitySetMapping(String entitySetName) {
            EntityUtil.CheckArgumentNull(entitySetName, "entitySetName"); 
            //Key for EntitySetMapping should be EntitySet name and Entoty type name
            StorageSetMapping setMapping = null;
            m_entitySetMappings.TryGetValue(entitySetName, out setMapping);
            return setMapping; 
        }
 
        ///  
        /// Get a RelationShip set mapping based upon the name of the relationship set
        ///  
        /// the name of the relationship set
        /// the mapping for the entity set if it exists, null if it does not exist
        internal StorageSetMapping GetRelationshipSetMapping(string relationshipSetName) {
            EntityUtil.CheckArgumentNull(relationshipSetName, "relationshipSetName"); 
            StorageSetMapping setMapping = null;
            m_associationSetMappings.TryGetValue(relationshipSetName, out setMapping); 
            return setMapping; 
        }
 
        /// 
        /// Get a RelationShipSet mapping that has the passed in EntitySet as one of the ends and is mapped to the
        /// table.
        ///  
        internal IEnumerable GetRelationshipSetMappingsFor(EntitySetBase edmEntitySet, EntitySetBase storeEntitySet )
        { 
            //First select the association set maps that are mapped to this table 
            IEnumerable associationSetMappings = m_associationSetMappings.Values.Cast().Where(w => ((w.StoreEntitySet != null) && (w.StoreEntitySet == storeEntitySet)));
            //From this again filter the ones that have the specified EntitySet on atleast one end 
            associationSetMappings = associationSetMappings.Where(associationSetMap => ((associationSetMap.Set as AssociationSet).AssociationSetEnds.Any(associationSetEnd => associationSetEnd.EntitySet == edmEntitySet)));
            return associationSetMappings;
        }
 

        ///  
        /// Get a set mapping based upon the name of the set 
        /// 
        ///  
        /// 
        internal StorageSetMapping GetSetMapping(string setName)
        {
            StorageSetMapping setMap = GetEntitySetMapping(setName); 
            if (setMap == null)
            { 
                setMap = GetRelationshipSetMapping(setName); 
            }
            return setMap; 
        }


        ///  
        /// Adds an entity set mapping to the list of EntitySetMaps
        /// under this entity container mapping. The method will be called 
        /// by the Mapping loader. 
        /// 
        internal void AddEntitySetMapping(StorageSetMapping setMapping) { 
            if (!this.m_entitySetMappings.ContainsKey(setMapping.Set.Name))
                this.m_entitySetMappings.Add(setMapping.Set.Name, setMapping);
        }
 
        /// 
        /// Adds a association set mapping to the list of AssociationSetMaps 
        /// under this entity container mapping. The method will be called 
        /// by the Mapping loader.
        ///  
        internal void AddAssociationSetMapping(StorageSetMapping setMapping) {
            this.m_associationSetMappings.Add(setMapping.Set.Name, setMapping);
        }
 
        /// 
        /// check whether the EntityContainerMapping contains 
        /// the map for the given AssociationSet 
        /// 
        ///  
        /// 
        internal bool ContainsAssociationSetMapping(AssociationSet associationSet) {
            return this.m_associationSetMappings.ContainsKey(associationSet.Name);
        } 

        ///  
        /// Returns whether the Set Map for the given set has a query view or not 
        /// 
        ///  
        /// 
        internal bool HasQueryViewForSetMap(string setName)
        {
            StorageSetMapping set = GetSetMapping(setName); 
            if (set != null)
            { 
                return (set.QueryView != null); 
            }
            return false; 
        }


        /// 
        /// The method builds up the spaces required for pretty printing each
        /// part of the mapping. 
        /// 
        internal static string GetPrettyPrintString(ref int index) {
 
            string spaces = "";
            spaces = spaces.PadLeft(index, ' ');
            Console.WriteLine(spaces + "|");
            Console.WriteLine(spaces + "|"); 
            index++;
            spaces = spaces.PadLeft(index, ' '); 
            Console.Write(spaces + "-"); 
            index++;
            spaces = spaces.PadLeft(index, ' '); 
            Console.Write("-");
            index++;
            spaces = spaces.PadLeft(index, ' ');
            return spaces; 
        }
 
 
        /// 
        /// This method is primarily for debugging purposes. 
        /// Will be removed shortly.
        /// 
        /// 
        internal void Print(int index) { 
            string spaces = "";
            StringBuilder sb = new StringBuilder(); 
            sb.Append(spaces); 
            sb.Append("EntityContainerMapping");
            sb.Append("   "); 
            sb.Append("Name:");
            sb.Append(this.m_entityContainer.Name);
            sb.Append("   ");
            Console.WriteLine(sb.ToString()); 
            foreach (StorageSetMapping extentMapping in m_entitySetMappings.Values) {
                extentMapping.Print(index + 5); 
            } 
            foreach (StorageSetMapping extentMapping in m_associationSetMappings.Values) {
                extentMapping.Print(index + 5); 
            }
        }

 
        // Methods to modify and access function imports, which association a "functionImport" declared
        // in the model entity container with a targetFunction declared in the target 
        internal void AddFunctionImportMapping(EdmFunction functionImport, FunctionImportMapping targetFunction) 
        {
            m_functionImportMappings.Add(functionImport, targetFunction); 
        }

        internal bool TryGetFunctionImportMapping(EdmFunction functionImport, out FunctionImportMapping targetFunction)
        { 
            return m_functionImportMappings.TryGetValue(functionImport, out targetFunction);
        } 
 
        internal OutputFromComputeCellGroups GetCellgroups(InputForComputingCellGroups args)
        { 
            Debug.Assert(object.ReferenceEquals(this, args.ContainerMapping));
            return m_memoizedCellGroupEvaluator.Evaluate(args);
        }
 
        private OutputFromComputeCellGroups ComputeCellGroups(InputForComputingCellGroups args)
        { 
            OutputFromComputeCellGroups result = new OutputFromComputeCellGroups(); 
            result.Success = true;
 
            //Don't want to cache on workspace because workspace may change
            MetadataWorkspace workspace = new MetadataWorkspace();
            workspace.RegisterItemCollection(args.ContainerMapping.StorageMappingItemCollection.EdmItemCollection);
            workspace.RegisterItemCollection(args.ContainerMapping.StorageMappingItemCollection.StoreItemCollection); 
            workspace.RegisterItemCollection(args.ContainerMapping.StorageMappingItemCollection);
 
            CellCreator cellCreator = new CellCreator(args.ContainerMapping, workspace); 
            result.Cells = cellCreator.GenerateCells(args.Config);
            result.Identifiers = cellCreator.Identifiers; 

            if (result.Cells.Count <= 0)
            {
                //When type-specific QVs are asked for but not defined in the MSL we should return without generating 
                // Query pipeline will handle this appropriately by asking for UNION ALL view.
                result.Success = false; 
                return result; 
            }
 
            result.ForeignKeyConstraints = ForeignConstraint.GetForeignConstraints(args.ContainerMapping.StorageEntityContainer, workspace);

            // Go through each table and determine their foreign key constraints
            CellPartitioner partitioner = new CellPartitioner(result.Cells, result.ForeignKeyConstraints); 
            List cellGroups = partitioner.GroupRelatedCells();
 
            //Clone cell groups- i.e, List> - upto cell before storing it in the cache because viewgen modified the Cell structure 
            result.CellGroups = cellGroups.Select(setOfcells => new CellGroup(setOfcells.Select(cell => new Cell(cell)))).ToList();
 
            return result;
        }

        #endregion 
    }
 
    internal struct InputForComputingCellGroups : IEquatable, IEqualityComparer 
    {
        internal readonly StorageEntityContainerMapping ContainerMapping; 
        internal readonly ConfigViewGenerator Config;

        internal InputForComputingCellGroups(StorageEntityContainerMapping containerMapping, ConfigViewGenerator config)
        { 
            this.ContainerMapping = containerMapping;
            this.Config = config; 
        } 

        public bool Equals(InputForComputingCellGroups other) 
        {
            // Isn't this funny? We are not using Memoizer for function memoization. Args Entity and Config don't matter!
            // If I were to compare Entity this would not use the cache for cases when I supply different entity set. However,
            // the cell groups belong to ALL entity sets. 
            return (this.ContainerMapping.Equals(other.ContainerMapping)
                && this.Config.Equals(other.Config)); 
        } 

        public bool Equals(InputForComputingCellGroups one, InputForComputingCellGroups two) 
        {
            if (object.ReferenceEquals(one, two))
            {
                return true; 
            }
            if (object.ReferenceEquals(one, null) || object.ReferenceEquals(two, null)) 
            { 
                return false;
            } 

            return one.Equals(two);
        }
 
        public int GetHashCode(InputForComputingCellGroups value)
        { 
            if (value == null) 
            {
                return 0; 
            }

            return value.GetHashCode();
        } 

        public override int GetHashCode() 
        { 
            return this.ContainerMapping.GetHashCode();
        } 

        public override bool Equals(object obj)
        {
            if (obj is InputForComputingCellGroups) 
            {
                return Equals((InputForComputingCellGroups)obj); 
            } 
            else
            { 
                return false;
            }
        }
 
        public static bool operator ==(InputForComputingCellGroups input1, InputForComputingCellGroups input2)
        { 
            if (object.ReferenceEquals(input1, input2)) 
            {
                return true; 
            }
            return input1.Equals(input2);
        }
 
        public static bool operator !=(InputForComputingCellGroups input1, InputForComputingCellGroups input2)
        { 
            return !(input1 == input2); 
        }
 
    }

    internal struct OutputFromComputeCellGroups
    { 
        internal List Cells;
        internal CqlIdentifiers Identifiers; 
        internal List CellGroups; 
        internal List ForeignKeyConstraints;
        internal bool Success; 
    }
}

// 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