StorageMappingItemCollection.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Mapping / StorageMappingItemCollection.cs / 2 / StorageMappingItemCollection.cs

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

using System; 
using System.Data.Common.Utils;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic; 
using System.Collections.ObjectModel;
using System.Data.EntityModel; 
using System.Text; 
using System.Xml.Serialization;
using System.Xml; 
using System.Xml.Schema;
using System.IO;
using System.Data.Common.CommandTrees;
using System.Data.Metadata.Edm; 
using System.Data.Mapping.ViewGeneration;
using System.Reflection; 
using System.Data.Mapping.ViewGeneration.Utils; 
using System.Security.Cryptography;
using System.Xml.XPath; 
using System.Linq;
using System.Data.Mapping.Update.Internal;
using som = System.Data.EntityModel.SchemaObjectModel;
using System.Data.Entity; 

namespace System.Data.Mapping 
{ 
    using OfTypeQVCacheKey = Pair>;
 
    /// 
    /// Class for representing a collection of items in Storage Mapping( CS Mapping) space.
    /// 
    public partial class StorageMappingItemCollection : MappingItemCollection 
    {
 
        #region Fields 
        //EdmItemCollection that is associated with the MSL Loader.
        private EdmItemCollection m_edmCollection; 

        //StoreItemCollection that is associated with the MSL Loader.
        private StoreItemCollection m_storeItemCollection;
        private ViewDictionary m_viewDictionary; 

 
 
        // In this version, we won't allow same types in CSpace to map to different types in store. If the same type
        // need to be reused, the store type must be the same. To keep track of this, we need to keep track of the member 
        // mapping across maps to make sure they are mapped to the same store side.
        // The first TypeUsage in the KeyValuePair stores the store equivalent type for the cspace member type and the second
        // one store the actual store type to which the member is mapped to.
        // For e.g. If the CSpace member of type Edm.Int32 maps to a sspace member of type SqlServer.bigint, then the KeyValuePair 
        // for the cspace member will contain SqlServer.int (store equivalent for Edm.Int32) and SqlServer.bigint (Actual store type
        // to which the member was mapped to) 
        private Dictionary> m_memberMappings = new Dictionary>(); 
        private ViewLoader _viewLoader;
 
        private Memoizer, ReadOnlyCollection> _cacheRequiredOriginalValueMembers;

        #endregion
 
        #region Constructors
 
        ///  
        /// constructor that takes in a list of ffolder or files or a mix of both and
        /// creates metadata for mapping in all the files. 
        /// 
        /// 
        /// 
        ///  
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
        public StorageMappingItemCollection(EdmItemCollection edmCollection, StoreItemCollection storeCollection, 
            params string[] filePaths) 
            : base(DataSpace.CSSpace)
        { 
            EntityUtil.CheckArgumentNull(edmCollection, "edmCollection");
            EntityUtil.CheckArgumentNull(storeCollection, "storeCollection");
            EntityUtil.CheckArgumentNull(filePaths, "filePaths");
 
            this.m_edmCollection = edmCollection;
            this.m_storeItemCollection = storeCollection; 
 
            // Wrap the file paths in instances of the MetadataArtifactLoader class, which provides
            // an abstraction and a uniform interface over a diverse set of metadata artifacts. 
            //
            MetadataArtifactLoader composite = null;
            List readers = null;
            try 
            {
                composite = MetadataArtifactLoader.CreateCompositeFromFilePaths(filePaths, XmlConstants.CSSpaceSchemaExtension); 
                readers = composite.CreateReaders(DataSpace.CSSpace); 

                this.Init(edmCollection, storeCollection, readers, 
                          composite.GetPaths(DataSpace.CSSpace), true /*throwOnError*/);
            }
            finally
            { 
                if (readers != null)
                { 
                    Helper.DisposeXmlReaders(readers); 
                }
            } 
        }

        /// 
        /// constructor that takes in a list of XmlReaders and creates metadata for mapping 
        /// in all the files.
        ///  
        /// The edm metadata collection that this mapping is to use 
        /// The store metadata collection that this mapping is to use
        /// The XmlReaders to load mapping from 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
        public StorageMappingItemCollection(EdmItemCollection edmCollection,
                                            StoreItemCollection storeCollection,
                                            IEnumerable xmlReaders) 
            : base(DataSpace.CSSpace)
        { 
            EntityUtil.CheckArgumentNull(xmlReaders, "xmlReaders"); 

            MetadataArtifactLoader composite = MetadataArtifactLoader.CreateCompositeFromXmlReaders(xmlReaders); 

            this.Init(edmCollection,
                      storeCollection,
                      composite.GetReaders(),   // filter out duplicates 
                      composite.GetPaths(),
                      true /* throwOnError*/); 
 
        }
 
        /// 
        /// constructor that takes in a list of XmlReaders and creates metadata for mapping
        /// in all the files.
        ///  
        /// The edm metadata collection that this mapping is to use
        /// The store metadata collection that this mapping is to use 
        /// Mapping URIs 
        /// The XmlReaders to load mapping from
        /// a list of errors for each file loaded 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] // referenced by System.Data.Entity.Design.dll
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        internal StorageMappingItemCollection(EdmItemCollection edmCollection,
                                              StoreItemCollection storeCollection, 
                                              IEnumerable xmlReaders,
                                              List filePaths, 
                                              out IList errors) 
            : base(DataSpace.CSSpace)
        { 
            errors = this.Init(edmCollection, storeCollection, xmlReaders, filePaths, false /*throwOnError*/);
        }

        ///  
        /// constructor that takes in a list of XmlReaders and creates metadata for mapping
        /// in all the files. 
        ///  
        /// The edm metadata collection that this mapping is to use
        /// The store metadata collection that this mapping is to use 
        /// Mapping URIs
        /// The XmlReaders to load mapping from
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        internal StorageMappingItemCollection(EdmItemCollection edmCollection, 
                                              StoreItemCollection storeCollection,
                                              IEnumerable xmlReaders, 
                                              List filePaths) 
            : base(DataSpace.CSSpace)
        { 
            this.Init(edmCollection, storeCollection, xmlReaders, filePaths, true /*throwOnError*/);
        }

        ///  
        /// Initializer that takes in a list of XmlReaders and creates metadata for mapping
        /// in all the files. 
        ///  
        /// The edm metadata collection that this mapping is to use
        /// The store metadata collection that this mapping is to use 
        /// Mapping URIs
        /// The XmlReaders to load mapping from
        /// a list of errors for each file loaded
        private IList Init(EdmItemCollection edmCollection, 
                          StoreItemCollection storeCollection,
                          IEnumerable xmlReaders, 
                          List filePaths, 
                          bool throwOnError)
        { 
            EntityUtil.CheckArgumentNull(xmlReaders, "xmlReaders");
            EntityUtil.CheckArgumentNull(edmCollection, "edmCollection");
            EntityUtil.CheckArgumentNull(storeCollection, "storeCollection");
 
            this.m_edmCollection = edmCollection;
            this.m_storeItemCollection = storeCollection; 
 
            Dictionary userDefinedQueryViewsDict;
            Dictionary userDefinedQueryViewsOfTypeDict; 

            this.m_viewDictionary = new ViewDictionary(this, out userDefinedQueryViewsDict, out userDefinedQueryViewsOfTypeDict);

            IList errors = LoadItems(xmlReaders, filePaths, userDefinedQueryViewsDict, userDefinedQueryViewsOfTypeDict); 
            Debug.Assert(errors != null);
 
            if (throwOnError && errors.Count != 0) 
            {
                if (!System.Data.Common.Utils.MetadataHelper.CheckIfAllErrorsAreWarnings(errors)) 
                {
                    // NOTE: not using Strings.InvalidSchemaEncountered because it will truncate the errors list.
                    throw new MappingException(
                    String.Format(System.Globalization.CultureInfo.CurrentCulture, 
                                  EntityRes.GetString(EntityRes.InvalidSchemaEncountered),
                                  Helper.CombineErrorMessage(errors))); 
                } 
            }
 
            return errors;
        }

        #endregion Constructors 

        ///  
        /// Return the EdmItemCollection associated with the Mapping Collection 
        /// 
        internal EdmItemCollection EdmItemCollection 
        {
            get
            {
                return this.m_edmCollection; 
            }
        } 
 
        /// 
        /// Return the StoreItemCollection associated with the Mapping Collection 
        /// 
        internal StoreItemCollection StoreItemCollection
        {
            get 
            {
                return this.m_storeItemCollection; 
            } 
        }
 
        /// 
        /// Search for a Mapping metadata with the specified type key.
        /// 
        /// identity of the type 
        /// The dataspace that the type for which map needs to be returned belongs to
        /// true for case-insensitive lookup 
        ///  Thrown if mapping space is not valid 
        internal override Map GetMap(string identity, DataSpace typeSpace, bool ignoreCase)
        { 
            EntityUtil.CheckArgumentNull(identity, "identity");
            if (typeSpace != DataSpace.CSpace)
            {
                throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.Mapping_Storage_InvalidSpace_1(typeSpace)); 
            }
            return GetItem(identity, ignoreCase); 
        } 

        ///  
        /// Search for a Mapping metadata with the specified type key.
        /// 
        /// identity of the type
        /// The dataspace that the type for which map needs to be returned belongs to 
        /// true for case-insensitive lookup
        ///  
        /// Returns false if no match found. 
        internal override bool TryGetMap(string identity, DataSpace typeSpace, bool ignoreCase, out Map map)
        { 
            if (typeSpace != DataSpace.CSpace)
            {
                throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.Mapping_Storage_InvalidSpace_1(typeSpace));
            } 
            return TryGetItem(identity, ignoreCase, out map);
        } 
 
        /// 
        /// Search for a Mapping metadata with the specified type key. 
        /// 
        /// identity of the type
        /// The dataspace that the type for which map needs to be returned belongs to
        ///  Thrown if mapping space is not valid 
        internal override Map GetMap(string identity, DataSpace typeSpace)
        { 
            return this.GetMap(identity, typeSpace, false /*ignoreCase*/); 
        }
 
        /// 
        /// Search for a Mapping metadata with the specified type key.
        /// 
        /// identity of the type 
        /// The dataspace that the type for which map needs to be returned belongs to
        ///  
        /// Returns false if no match found. 
        internal override bool TryGetMap(string identity, DataSpace typeSpace, out Map map)
        { 
            return this.TryGetMap(identity, typeSpace, false /*ignoreCase*/, out map);
        }

        ///  
        /// Search for a Mapping metadata with the specified type key.
        ///  
        ///  
        internal override Map GetMap(GlobalItem item)
        { 
            EntityUtil.CheckArgumentNull(item, "item");
            DataSpace typeSpace = item.DataSpace;
            if (typeSpace != DataSpace.CSpace)
            { 
                throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.Mapping_Storage_InvalidSpace_1(typeSpace));
            } 
            return this.GetMap(item.Identity, typeSpace); 
        }
 
        /// 
        /// Search for a Mapping metadata with the specified type key.
        /// 
        ///  
        /// 
        /// Returns false if no match found. 
        internal override bool TryGetMap(GlobalItem item, out Map map) 
        {
            if (item == null) 
            {
                map = null;
                return false;
            } 
            DataSpace typeSpace = item.DataSpace;
            if (typeSpace != DataSpace.CSpace) 
            { 
                map = null;
                return false; 
            }
            return this.TryGetMap(item.Identity, typeSpace, out map);
        }
 

        ///  
        /// Call the View Generator's Generate view method 
        /// for each entity container map in this collection.
        /// Add these views to the dictionary and return the dictionary( whose key is EntitySetBase 
        /// and value is Esql String ) to the caller.
        /// Calling this method won't add the generated views to the item collection since this is
        /// supposed to be called only during the design time.
        ///  
        /// 
        ///  
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] // referenced by System.Data.Entity.Design.dll 
        internal Dictionary GetViews(MetadataWorkspace workspace, out IList errors)
        { 
            Dictionary esqlViews = new Dictionary();
            errors = new List();
            ReadOnlyCollection entityContainerMappings = GetItems();
            foreach (StorageEntityContainerMapping entityContainerMap in entityContainerMappings) 
            {
                Debug.Assert(entityContainerMap != null, "Mapping Item Collection should have only Entity Container Maps"); 
                //If there are no entity set maps, don't call the view generation process 
                if (entityContainerMap.IsEmpty)
                { 
                    return esqlViews;
                }
                //If entityContainerMap just cotains queryview, then add an warning to the errors and continue to next mapping
                if (!this.HasMappingFragment(entityContainerMap)) 
                {
                    errors.Add(new EdmSchemaError( 
                        Strings.Mapping_AllQueryViewAtCompileTime(entityContainerMap.Identity), 
                        (int)StorageMappingErrorCode.MappingAllQueryViewAtCompileTime,
                        EdmSchemaErrorSeverity.Warning)); 
                    continue;
                }

                ViewGenResults viewGenResults = ViewGenerator.GenerateViewsForSchema(entityContainerMap, workspace, new ConfigViewGenerator()); 
                if (viewGenResults.HasErrors)
                { 
                    errors = new List(viewGenResults.Errors); 
                }
                KeyToListMap extentMappingViews = viewGenResults.Views; 
                foreach (KeyValuePair> extentViewPair in extentMappingViews.KeyValuePairs)
                {
                    List generatedViews = extentViewPair.Value;
                    //Multiple Views are returned for an extent but the first view 
                    //is the only one that we will use for now. In the future,
                    //we might start using the other views which are per type within an extent. 
                    esqlViews.Add(extentViewPair.Key, generatedViews[0].CqlString); 
                }
            } 

            bool allEntityContainerMappingsAreInvalid =
                errors.Where(e=>e.ErrorCode == (int)StorageMappingErrorCode.MappingAllQueryViewAtCompileTime)
                    .Count() == entityContainerMappings.Count; 

            if (entityContainerMappings.Count > 0 && allEntityContainerMappingsAreInvalid) 
            { 
                errors.Add(new EdmSchemaError(
                                       Strings.Mapping_NoViewsCanBeGenerated, 
                                       (int)StorageMappingErrorCode.MappingNoViewsCanBeGenerated,
                                       EdmSchemaErrorSeverity.Error));
            }
            return esqlViews; 
        }
 
        private bool HasMappingFragment(StorageEntityContainerMapping mapping) 
        {
            foreach (var extentMap in mapping.AllSetMaps) 
            {
                foreach (var typeMap in extentMap.TypeMappings)
                {
                    if (typeMap.MappingFragments.Count > 0) 
                    {
                        return true; 
                    } 
                }
            } 
            return false;
        }

        internal ReadOnlyCollection GetRequiredOriginalValueMembers(Pair arguments) 
        {
            if (null == _cacheRequiredOriginalValueMembers) 
            { 
                var cacheRequiredOriginalValueMembers = new Memoizer, ReadOnlyCollection>(ComputeRequiredOriginalValueMembers, Pair.PairComparer.Instance);
                System.Threading.Interlocked.CompareExchange(ref _cacheRequiredOriginalValueMembers, cacheRequiredOriginalValueMembers, null); 
            }
            return _cacheRequiredOriginalValueMembers.Evaluate(arguments);
        }
 
        private ReadOnlyCollection ComputeRequiredOriginalValueMembers(Pair arguments)
        { 
            EntitySetBase entitySet = arguments.First; 
            EntityTypeBase entityType = arguments.Second;
            List result; 
            result = new List();

            foreach (var propMap in
                MappingMetadataHelper.GetMappingsForEntitySetAndSuperTypes(this, entitySet.EntityContainer, entitySet, entityType) 
                    .SelectMany(stm => stm.MappingFragments.SelectMany(mf => mf.AllProperties)))
            { 
                FindIfPropertyRequiresOriginalValue(propMap, ref result); 
            }
 
            //(4) Members in update ModificationFunction with Version="Original" are "interesting"
            // This also works when you have complex-types (4.1)
            foreach (var functionMappings in MappingMetadataHelper.GetFunctionMappingsForEntitySetAndType(this, entitySet.EntityContainer, entitySet, entityType))
            { 
                if (functionMappings.UpdateFunctionMapping != null)
                { 
                    foreach (var parameterBinding in functionMappings.UpdateFunctionMapping.ParameterBindings.Where(p => !p.IsCurrent)) 
                    {
                        //Last is the root element (with respect to the Entity) 
                        //For example,  Entity1={
                        //                  S1,
                        //                  C1{S2,
                        //                     C2{ S3, S4 } 
                        //                     },
                        //                  S5} 
                        // if S4 matches (i.e. C1.C2.S4), then it returns C1 
                        //because internally the list is [S4][C2][C1]
                        result.Add(parameterBinding.MemberPath.Members.Last()); 
                    }
                }
            }
 
            result = result.Distinct().ToList(); //E.g: A single C-member participating in condition may appear in more than one fragment
            return new ReadOnlyCollection(result); 
        } 

        private void FindIfPropertyRequiresOriginalValue(StoragePropertyMapping propMap, ref List result) 
        {
            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");

            //scalar property
            if (scalarPropMap != null && scalarPropMap.EdmProperty != null) 
            {
                // (0) if a member is part of the key it is interesting 
                if (MetadataHelper.IsPartOfEntityTypeKey(scalarPropMap.EdmProperty)) 
                {
                    result.Add(scalarPropMap.EdmProperty); 
                }
                //(3) if a scalar property has Fixed concurrency mode then it is "interesting"
                else if (MetadataHelper.GetConcurrencyMode(scalarPropMap.EdmProperty) == ConcurrencyMode.Fixed)
                { 
                    result.Add(scalarPropMap.EdmProperty);
                } 
            } 
            else if (complexPropMap != null)
            { 
                //(3.1) The complex property or its one of its children has fixed CC mode
                if (MetadataHelper.GetConcurrencyMode(complexPropMap.EdmProperty) == ConcurrencyMode.Fixed || HasFixedConcurrencyModeInAnyChildProperty(complexPropMap))
                {
                    result.Add(complexPropMap.EdmProperty); 
                }
            } 
            else if (associationEndPropertypMap != null) 
            {
                //(2) Ends participating in association are "interesting" 
                result.Add(associationEndPropertypMap.EndMember);
            }
            else if (conditionMap != null)
            { 
                //(1) C-Side condition members are 'interesting'
                if (conditionMap.EdmProperty != null) 
                { 
                    result.Add(conditionMap.EdmProperty);
                } 
            }
        }

        ///  
        /// Recurse down the complex property
        ///  
        private bool HasFixedConcurrencyModeInAnyChildProperty(StorageComplexPropertyMapping complexMapping) 
        {
            foreach (StoragePropertyMapping propertyMapping in complexMapping.TypeMappings.SelectMany(m => m.AllProperties)) 
            {
                StorageScalarPropertyMapping childScalarPropMap = propertyMapping as StorageScalarPropertyMapping;
                StorageComplexPropertyMapping childComplexPropMap = propertyMapping as StorageComplexPropertyMapping;
 
                Debug.Assert(childScalarPropMap != null ||
                             childComplexPropMap != null, "Unimplemented property mapping for complex property"); 
 
                //scalar property and has Fixed CC mode
                if (childScalarPropMap != null && MetadataHelper.GetConcurrencyMode(childScalarPropMap.EdmProperty) == ConcurrencyMode.Fixed) 
                {
                    return true;
                }
                // Complex Prop and sub-properties or itself has fixed CC mode 
                else if (childComplexPropMap != null &&
                    (MetadataHelper.GetConcurrencyMode(childComplexPropMap.EdmProperty) == ConcurrencyMode.Fixed 
                        || HasFixedConcurrencyModeInAnyChildProperty(childComplexPropMap))) 
                {
                    return true; 
                }
            }

            return false; 
        }
 
        ///  
        /// call the view dictionary to load the view, see detailed comments in the view dictionary class
        ///  
        /// 
        /// 
        /// 
        internal GeneratedView GetGeneratedView(EntitySetBase extent, MetadataWorkspace workspace) 
        {
            return this.m_viewDictionary.GetGeneratedView(extent, workspace, this); 
        } 

        ///  
        /// Attempts to find a mapping for the given function import.
        /// 
        /// Import declared in an entity container.
        /// Current workspace. 
        /// Returns target (store) function to which the import is mapped.
        /// true if a mapping is found; false otherwise 
        internal static bool TryGetFunctionImportTarget(EdmFunction functionImport, MetadataWorkspace workspace, out FunctionImportMapping targetFunction) 
        {
            Debug.Assert(null != functionImport); 
            Debug.Assert(null != workspace);
            // Retrieve entity container mappings
            ReadOnlyCollection entityContainerMaps =
                workspace.GetItems(DataSpace.CSSpace); 
            foreach (StorageEntityContainerMapping containerMapping in entityContainerMaps)
            { 
                if (containerMapping.TryGetFunctionImportMapping(functionImport, out targetFunction)) 
                {
                    return true; 
                }
            }
            targetFunction = null;
            return false; 
        }
 
        // Add to the cache. If it is already present, then throw an exception 
        private void AddInternal(StorageEntityContainerMapping storageMap)
        { 
            storageMap.DataSpace = DataSpace.CSSpace;
            try
            {
                base.AddInternal(storageMap); 
            }
            catch (ArgumentException e) 
            { 
                throw new MappingException(System.Data.Entity.Strings.Mapping_Duplicate_Type_1(
                    storageMap.EdmItem.Identity), e); 
            }
        }

        // Contains whether the given StorageEntityContainerName 
        internal bool ContainsStorageEntityContainer(string storageEntityContainerName)
        { 
            ReadOnlyCollection entityContainerMaps = 
                this.GetItems();
            return entityContainerMaps.Any(map => map.StorageEntityContainer.Name.Equals(storageEntityContainerName, StringComparison.Ordinal)); 
        }


        ///  
        /// This helper method loads items based on contents of in-memory XmlReader instances.
        /// Assumption: This method is called only from the constructor because m_extentMappingViews is not thread safe. 
        ///  
        /// A list of XmlReader instances
        /// A list of URIs 
        /// A list of schema errors
        private List LoadItems(IEnumerable xmlReaders,
                                        List mappingSchemaUris,
                                        Dictionary userDefinedQueryViewsDict, 
                                        Dictionary userDefinedQueryViewsOfTypeDict)
        { 
            Debug.Assert(m_memberMappings.Count == 0, "Assumption: This method is called only once, and from the constructor because m_extentMappingViews is not thread safe."); 

            List errors = new List(); 

            int index = -1;
            foreach (XmlReader xmlReader in xmlReaders)
            { 
                index++;
                string location = null; 
                if (mappingSchemaUris == null) 
                {
                    som.SchemaManager.TryGetBaseUri(xmlReader, out location); 
                }
                else
                {
                    location = mappingSchemaUris[index]; 
                }
 
                StorageMappingItemLoader mapLoader = new StorageMappingItemLoader( 
                                                            this,
                                                            location,  // ASSUMPTION: location is only used for generating error-messages 
                                                            m_memberMappings);

                IList schemaErrors = mapLoader.ParsingErrors;
                StorageEntityContainerMapping containerMapping = mapLoader.LoadMappingItems(xmlReader); 

                if (mapLoader.HasQueryViews && containerMapping != null) 
                { 
                    //Parse the query views so that we can report the errors in the user specified views
                    ViewDictionary.CollectViews(containerMapping, this, schemaErrors, userDefinedQueryViewsDict, userDefinedQueryViewsOfTypeDict); 
                }

                // Add container mapping if there are no errors and entity container mapping is not already present
                if (MetadataHelper.CheckIfAllErrorsAreWarnings(schemaErrors) && 
                    !this.Contains(containerMapping))
                { 
                    AddInternal(containerMapping); 
                }
                errors.AddRange(schemaErrors); 
            }

            CheckForDuplicateItems(EdmItemCollection, StoreItemCollection, errors);
 
            return errors;
        } 
 

        ///  
        /// Return the update view loader
        /// 
        /// 
        internal ViewLoader GetUpdateViewLoader() 
        {
            if (_viewLoader == null) 
            { 
                _viewLoader = new ViewLoader(this);
            } 

            return _viewLoader;
        }
 
        /// 
        /// this method will be called in metadatworkspace, the signature is the same as the one in ViewDictionary 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        internal bool TryGetGeneratedViewOfType(MetadataWorkspace workspace, EntitySetBase entity, EntityTypeBase type, bool includeSubtypes, out GeneratedView generatedView)
        { 
            return this.m_viewDictionary.TryGetGeneratedViewOfType(workspace, entity, type, includeSubtypes, out generatedView); 
        }
 
        // Check for duplicate items (items with same name) in edm item collection and store item collection. Mapping is the only logical place to do this.
        // The only other place is workspace, but that is at the time of registering item collections (only when the second one gets registered) and we
        // will have to throw exceptions at that time. If we do this check in mapping, we might throw error in a more consistent way (by adding it to error
        // collection). Also if someone is just creating item collection, and not registering it with workspace (tools), doing it in mapping makes more sense 
        private static void CheckForDuplicateItems(EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection, List errorCollection)
        { 
            Debug.Assert(edmItemCollection != null && storeItemCollection != null && errorCollection != null, "The parameters must not be null in CheckForDuplicateItems"); 

            foreach (GlobalItem item in edmItemCollection) 
            {
                if (storeItemCollection.Contains(item.Identity))
                {
                    errorCollection.Add(new EdmSchemaError(System.Data.Entity.Strings.Mapping_ItemWithSameNameExistsBothInCSpaceAndSSpace(item.Identity), 
                                        (int)StorageMappingErrorCode.ItemWithSameNameExistsBothInCSpaceAndSSpace, EdmSchemaErrorSeverity.Error));
                } 
            } 
        }
    }//---- ItemCollection 

}//----

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

using System; 
using System.Data.Common.Utils;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic; 
using System.Collections.ObjectModel;
using System.Data.EntityModel; 
using System.Text; 
using System.Xml.Serialization;
using System.Xml; 
using System.Xml.Schema;
using System.IO;
using System.Data.Common.CommandTrees;
using System.Data.Metadata.Edm; 
using System.Data.Mapping.ViewGeneration;
using System.Reflection; 
using System.Data.Mapping.ViewGeneration.Utils; 
using System.Security.Cryptography;
using System.Xml.XPath; 
using System.Linq;
using System.Data.Mapping.Update.Internal;
using som = System.Data.EntityModel.SchemaObjectModel;
using System.Data.Entity; 

namespace System.Data.Mapping 
{ 
    using OfTypeQVCacheKey = Pair>;
 
    /// 
    /// Class for representing a collection of items in Storage Mapping( CS Mapping) space.
    /// 
    public partial class StorageMappingItemCollection : MappingItemCollection 
    {
 
        #region Fields 
        //EdmItemCollection that is associated with the MSL Loader.
        private EdmItemCollection m_edmCollection; 

        //StoreItemCollection that is associated with the MSL Loader.
        private StoreItemCollection m_storeItemCollection;
        private ViewDictionary m_viewDictionary; 

 
 
        // In this version, we won't allow same types in CSpace to map to different types in store. If the same type
        // need to be reused, the store type must be the same. To keep track of this, we need to keep track of the member 
        // mapping across maps to make sure they are mapped to the same store side.
        // The first TypeUsage in the KeyValuePair stores the store equivalent type for the cspace member type and the second
        // one store the actual store type to which the member is mapped to.
        // For e.g. If the CSpace member of type Edm.Int32 maps to a sspace member of type SqlServer.bigint, then the KeyValuePair 
        // for the cspace member will contain SqlServer.int (store equivalent for Edm.Int32) and SqlServer.bigint (Actual store type
        // to which the member was mapped to) 
        private Dictionary> m_memberMappings = new Dictionary>(); 
        private ViewLoader _viewLoader;
 
        private Memoizer, ReadOnlyCollection> _cacheRequiredOriginalValueMembers;

        #endregion
 
        #region Constructors
 
        ///  
        /// constructor that takes in a list of ffolder or files or a mix of both and
        /// creates metadata for mapping in all the files. 
        /// 
        /// 
        /// 
        ///  
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
        public StorageMappingItemCollection(EdmItemCollection edmCollection, StoreItemCollection storeCollection, 
            params string[] filePaths) 
            : base(DataSpace.CSSpace)
        { 
            EntityUtil.CheckArgumentNull(edmCollection, "edmCollection");
            EntityUtil.CheckArgumentNull(storeCollection, "storeCollection");
            EntityUtil.CheckArgumentNull(filePaths, "filePaths");
 
            this.m_edmCollection = edmCollection;
            this.m_storeItemCollection = storeCollection; 
 
            // Wrap the file paths in instances of the MetadataArtifactLoader class, which provides
            // an abstraction and a uniform interface over a diverse set of metadata artifacts. 
            //
            MetadataArtifactLoader composite = null;
            List readers = null;
            try 
            {
                composite = MetadataArtifactLoader.CreateCompositeFromFilePaths(filePaths, XmlConstants.CSSpaceSchemaExtension); 
                readers = composite.CreateReaders(DataSpace.CSSpace); 

                this.Init(edmCollection, storeCollection, readers, 
                          composite.GetPaths(DataSpace.CSSpace), true /*throwOnError*/);
            }
            finally
            { 
                if (readers != null)
                { 
                    Helper.DisposeXmlReaders(readers); 
                }
            } 
        }

        /// 
        /// constructor that takes in a list of XmlReaders and creates metadata for mapping 
        /// in all the files.
        ///  
        /// The edm metadata collection that this mapping is to use 
        /// The store metadata collection that this mapping is to use
        /// The XmlReaders to load mapping from 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
        public StorageMappingItemCollection(EdmItemCollection edmCollection,
                                            StoreItemCollection storeCollection,
                                            IEnumerable xmlReaders) 
            : base(DataSpace.CSSpace)
        { 
            EntityUtil.CheckArgumentNull(xmlReaders, "xmlReaders"); 

            MetadataArtifactLoader composite = MetadataArtifactLoader.CreateCompositeFromXmlReaders(xmlReaders); 

            this.Init(edmCollection,
                      storeCollection,
                      composite.GetReaders(),   // filter out duplicates 
                      composite.GetPaths(),
                      true /* throwOnError*/); 
 
        }
 
        /// 
        /// constructor that takes in a list of XmlReaders and creates metadata for mapping
        /// in all the files.
        ///  
        /// The edm metadata collection that this mapping is to use
        /// The store metadata collection that this mapping is to use 
        /// Mapping URIs 
        /// The XmlReaders to load mapping from
        /// a list of errors for each file loaded 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] // referenced by System.Data.Entity.Design.dll
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        internal StorageMappingItemCollection(EdmItemCollection edmCollection,
                                              StoreItemCollection storeCollection, 
                                              IEnumerable xmlReaders,
                                              List filePaths, 
                                              out IList errors) 
            : base(DataSpace.CSSpace)
        { 
            errors = this.Init(edmCollection, storeCollection, xmlReaders, filePaths, false /*throwOnError*/);
        }

        ///  
        /// constructor that takes in a list of XmlReaders and creates metadata for mapping
        /// in all the files. 
        ///  
        /// The edm metadata collection that this mapping is to use
        /// The store metadata collection that this mapping is to use 
        /// Mapping URIs
        /// The XmlReaders to load mapping from
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        internal StorageMappingItemCollection(EdmItemCollection edmCollection, 
                                              StoreItemCollection storeCollection,
                                              IEnumerable xmlReaders, 
                                              List filePaths) 
            : base(DataSpace.CSSpace)
        { 
            this.Init(edmCollection, storeCollection, xmlReaders, filePaths, true /*throwOnError*/);
        }

        ///  
        /// Initializer that takes in a list of XmlReaders and creates metadata for mapping
        /// in all the files. 
        ///  
        /// The edm metadata collection that this mapping is to use
        /// The store metadata collection that this mapping is to use 
        /// Mapping URIs
        /// The XmlReaders to load mapping from
        /// a list of errors for each file loaded
        private IList Init(EdmItemCollection edmCollection, 
                          StoreItemCollection storeCollection,
                          IEnumerable xmlReaders, 
                          List filePaths, 
                          bool throwOnError)
        { 
            EntityUtil.CheckArgumentNull(xmlReaders, "xmlReaders");
            EntityUtil.CheckArgumentNull(edmCollection, "edmCollection");
            EntityUtil.CheckArgumentNull(storeCollection, "storeCollection");
 
            this.m_edmCollection = edmCollection;
            this.m_storeItemCollection = storeCollection; 
 
            Dictionary userDefinedQueryViewsDict;
            Dictionary userDefinedQueryViewsOfTypeDict; 

            this.m_viewDictionary = new ViewDictionary(this, out userDefinedQueryViewsDict, out userDefinedQueryViewsOfTypeDict);

            IList errors = LoadItems(xmlReaders, filePaths, userDefinedQueryViewsDict, userDefinedQueryViewsOfTypeDict); 
            Debug.Assert(errors != null);
 
            if (throwOnError && errors.Count != 0) 
            {
                if (!System.Data.Common.Utils.MetadataHelper.CheckIfAllErrorsAreWarnings(errors)) 
                {
                    // NOTE: not using Strings.InvalidSchemaEncountered because it will truncate the errors list.
                    throw new MappingException(
                    String.Format(System.Globalization.CultureInfo.CurrentCulture, 
                                  EntityRes.GetString(EntityRes.InvalidSchemaEncountered),
                                  Helper.CombineErrorMessage(errors))); 
                } 
            }
 
            return errors;
        }

        #endregion Constructors 

        ///  
        /// Return the EdmItemCollection associated with the Mapping Collection 
        /// 
        internal EdmItemCollection EdmItemCollection 
        {
            get
            {
                return this.m_edmCollection; 
            }
        } 
 
        /// 
        /// Return the StoreItemCollection associated with the Mapping Collection 
        /// 
        internal StoreItemCollection StoreItemCollection
        {
            get 
            {
                return this.m_storeItemCollection; 
            } 
        }
 
        /// 
        /// Search for a Mapping metadata with the specified type key.
        /// 
        /// identity of the type 
        /// The dataspace that the type for which map needs to be returned belongs to
        /// true for case-insensitive lookup 
        ///  Thrown if mapping space is not valid 
        internal override Map GetMap(string identity, DataSpace typeSpace, bool ignoreCase)
        { 
            EntityUtil.CheckArgumentNull(identity, "identity");
            if (typeSpace != DataSpace.CSpace)
            {
                throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.Mapping_Storage_InvalidSpace_1(typeSpace)); 
            }
            return GetItem(identity, ignoreCase); 
        } 

        ///  
        /// Search for a Mapping metadata with the specified type key.
        /// 
        /// identity of the type
        /// The dataspace that the type for which map needs to be returned belongs to 
        /// true for case-insensitive lookup
        ///  
        /// Returns false if no match found. 
        internal override bool TryGetMap(string identity, DataSpace typeSpace, bool ignoreCase, out Map map)
        { 
            if (typeSpace != DataSpace.CSpace)
            {
                throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.Mapping_Storage_InvalidSpace_1(typeSpace));
            } 
            return TryGetItem(identity, ignoreCase, out map);
        } 
 
        /// 
        /// Search for a Mapping metadata with the specified type key. 
        /// 
        /// identity of the type
        /// The dataspace that the type for which map needs to be returned belongs to
        ///  Thrown if mapping space is not valid 
        internal override Map GetMap(string identity, DataSpace typeSpace)
        { 
            return this.GetMap(identity, typeSpace, false /*ignoreCase*/); 
        }
 
        /// 
        /// Search for a Mapping metadata with the specified type key.
        /// 
        /// identity of the type 
        /// The dataspace that the type for which map needs to be returned belongs to
        ///  
        /// Returns false if no match found. 
        internal override bool TryGetMap(string identity, DataSpace typeSpace, out Map map)
        { 
            return this.TryGetMap(identity, typeSpace, false /*ignoreCase*/, out map);
        }

        ///  
        /// Search for a Mapping metadata with the specified type key.
        ///  
        ///  
        internal override Map GetMap(GlobalItem item)
        { 
            EntityUtil.CheckArgumentNull(item, "item");
            DataSpace typeSpace = item.DataSpace;
            if (typeSpace != DataSpace.CSpace)
            { 
                throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.Mapping_Storage_InvalidSpace_1(typeSpace));
            } 
            return this.GetMap(item.Identity, typeSpace); 
        }
 
        /// 
        /// Search for a Mapping metadata with the specified type key.
        /// 
        ///  
        /// 
        /// Returns false if no match found. 
        internal override bool TryGetMap(GlobalItem item, out Map map) 
        {
            if (item == null) 
            {
                map = null;
                return false;
            } 
            DataSpace typeSpace = item.DataSpace;
            if (typeSpace != DataSpace.CSpace) 
            { 
                map = null;
                return false; 
            }
            return this.TryGetMap(item.Identity, typeSpace, out map);
        }
 

        ///  
        /// Call the View Generator's Generate view method 
        /// for each entity container map in this collection.
        /// Add these views to the dictionary and return the dictionary( whose key is EntitySetBase 
        /// and value is Esql String ) to the caller.
        /// Calling this method won't add the generated views to the item collection since this is
        /// supposed to be called only during the design time.
        ///  
        /// 
        ///  
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] // referenced by System.Data.Entity.Design.dll 
        internal Dictionary GetViews(MetadataWorkspace workspace, out IList errors)
        { 
            Dictionary esqlViews = new Dictionary();
            errors = new List();
            ReadOnlyCollection entityContainerMappings = GetItems();
            foreach (StorageEntityContainerMapping entityContainerMap in entityContainerMappings) 
            {
                Debug.Assert(entityContainerMap != null, "Mapping Item Collection should have only Entity Container Maps"); 
                //If there are no entity set maps, don't call the view generation process 
                if (entityContainerMap.IsEmpty)
                { 
                    return esqlViews;
                }
                //If entityContainerMap just cotains queryview, then add an warning to the errors and continue to next mapping
                if (!this.HasMappingFragment(entityContainerMap)) 
                {
                    errors.Add(new EdmSchemaError( 
                        Strings.Mapping_AllQueryViewAtCompileTime(entityContainerMap.Identity), 
                        (int)StorageMappingErrorCode.MappingAllQueryViewAtCompileTime,
                        EdmSchemaErrorSeverity.Warning)); 
                    continue;
                }

                ViewGenResults viewGenResults = ViewGenerator.GenerateViewsForSchema(entityContainerMap, workspace, new ConfigViewGenerator()); 
                if (viewGenResults.HasErrors)
                { 
                    errors = new List(viewGenResults.Errors); 
                }
                KeyToListMap extentMappingViews = viewGenResults.Views; 
                foreach (KeyValuePair> extentViewPair in extentMappingViews.KeyValuePairs)
                {
                    List generatedViews = extentViewPair.Value;
                    //Multiple Views are returned for an extent but the first view 
                    //is the only one that we will use for now. In the future,
                    //we might start using the other views which are per type within an extent. 
                    esqlViews.Add(extentViewPair.Key, generatedViews[0].CqlString); 
                }
            } 

            bool allEntityContainerMappingsAreInvalid =
                errors.Where(e=>e.ErrorCode == (int)StorageMappingErrorCode.MappingAllQueryViewAtCompileTime)
                    .Count() == entityContainerMappings.Count; 

            if (entityContainerMappings.Count > 0 && allEntityContainerMappingsAreInvalid) 
            { 
                errors.Add(new EdmSchemaError(
                                       Strings.Mapping_NoViewsCanBeGenerated, 
                                       (int)StorageMappingErrorCode.MappingNoViewsCanBeGenerated,
                                       EdmSchemaErrorSeverity.Error));
            }
            return esqlViews; 
        }
 
        private bool HasMappingFragment(StorageEntityContainerMapping mapping) 
        {
            foreach (var extentMap in mapping.AllSetMaps) 
            {
                foreach (var typeMap in extentMap.TypeMappings)
                {
                    if (typeMap.MappingFragments.Count > 0) 
                    {
                        return true; 
                    } 
                }
            } 
            return false;
        }

        internal ReadOnlyCollection GetRequiredOriginalValueMembers(Pair arguments) 
        {
            if (null == _cacheRequiredOriginalValueMembers) 
            { 
                var cacheRequiredOriginalValueMembers = new Memoizer, ReadOnlyCollection>(ComputeRequiredOriginalValueMembers, Pair.PairComparer.Instance);
                System.Threading.Interlocked.CompareExchange(ref _cacheRequiredOriginalValueMembers, cacheRequiredOriginalValueMembers, null); 
            }
            return _cacheRequiredOriginalValueMembers.Evaluate(arguments);
        }
 
        private ReadOnlyCollection ComputeRequiredOriginalValueMembers(Pair arguments)
        { 
            EntitySetBase entitySet = arguments.First; 
            EntityTypeBase entityType = arguments.Second;
            List result; 
            result = new List();

            foreach (var propMap in
                MappingMetadataHelper.GetMappingsForEntitySetAndSuperTypes(this, entitySet.EntityContainer, entitySet, entityType) 
                    .SelectMany(stm => stm.MappingFragments.SelectMany(mf => mf.AllProperties)))
            { 
                FindIfPropertyRequiresOriginalValue(propMap, ref result); 
            }
 
            //(4) Members in update ModificationFunction with Version="Original" are "interesting"
            // This also works when you have complex-types (4.1)
            foreach (var functionMappings in MappingMetadataHelper.GetFunctionMappingsForEntitySetAndType(this, entitySet.EntityContainer, entitySet, entityType))
            { 
                if (functionMappings.UpdateFunctionMapping != null)
                { 
                    foreach (var parameterBinding in functionMappings.UpdateFunctionMapping.ParameterBindings.Where(p => !p.IsCurrent)) 
                    {
                        //Last is the root element (with respect to the Entity) 
                        //For example,  Entity1={
                        //                  S1,
                        //                  C1{S2,
                        //                     C2{ S3, S4 } 
                        //                     },
                        //                  S5} 
                        // if S4 matches (i.e. C1.C2.S4), then it returns C1 
                        //because internally the list is [S4][C2][C1]
                        result.Add(parameterBinding.MemberPath.Members.Last()); 
                    }
                }
            }
 
            result = result.Distinct().ToList(); //E.g: A single C-member participating in condition may appear in more than one fragment
            return new ReadOnlyCollection(result); 
        } 

        private void FindIfPropertyRequiresOriginalValue(StoragePropertyMapping propMap, ref List result) 
        {
            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");

            //scalar property
            if (scalarPropMap != null && scalarPropMap.EdmProperty != null) 
            {
                // (0) if a member is part of the key it is interesting 
                if (MetadataHelper.IsPartOfEntityTypeKey(scalarPropMap.EdmProperty)) 
                {
                    result.Add(scalarPropMap.EdmProperty); 
                }
                //(3) if a scalar property has Fixed concurrency mode then it is "interesting"
                else if (MetadataHelper.GetConcurrencyMode(scalarPropMap.EdmProperty) == ConcurrencyMode.Fixed)
                { 
                    result.Add(scalarPropMap.EdmProperty);
                } 
            } 
            else if (complexPropMap != null)
            { 
                //(3.1) The complex property or its one of its children has fixed CC mode
                if (MetadataHelper.GetConcurrencyMode(complexPropMap.EdmProperty) == ConcurrencyMode.Fixed || HasFixedConcurrencyModeInAnyChildProperty(complexPropMap))
                {
                    result.Add(complexPropMap.EdmProperty); 
                }
            } 
            else if (associationEndPropertypMap != null) 
            {
                //(2) Ends participating in association are "interesting" 
                result.Add(associationEndPropertypMap.EndMember);
            }
            else if (conditionMap != null)
            { 
                //(1) C-Side condition members are 'interesting'
                if (conditionMap.EdmProperty != null) 
                { 
                    result.Add(conditionMap.EdmProperty);
                } 
            }
        }

        ///  
        /// Recurse down the complex property
        ///  
        private bool HasFixedConcurrencyModeInAnyChildProperty(StorageComplexPropertyMapping complexMapping) 
        {
            foreach (StoragePropertyMapping propertyMapping in complexMapping.TypeMappings.SelectMany(m => m.AllProperties)) 
            {
                StorageScalarPropertyMapping childScalarPropMap = propertyMapping as StorageScalarPropertyMapping;
                StorageComplexPropertyMapping childComplexPropMap = propertyMapping as StorageComplexPropertyMapping;
 
                Debug.Assert(childScalarPropMap != null ||
                             childComplexPropMap != null, "Unimplemented property mapping for complex property"); 
 
                //scalar property and has Fixed CC mode
                if (childScalarPropMap != null && MetadataHelper.GetConcurrencyMode(childScalarPropMap.EdmProperty) == ConcurrencyMode.Fixed) 
                {
                    return true;
                }
                // Complex Prop and sub-properties or itself has fixed CC mode 
                else if (childComplexPropMap != null &&
                    (MetadataHelper.GetConcurrencyMode(childComplexPropMap.EdmProperty) == ConcurrencyMode.Fixed 
                        || HasFixedConcurrencyModeInAnyChildProperty(childComplexPropMap))) 
                {
                    return true; 
                }
            }

            return false; 
        }
 
        ///  
        /// call the view dictionary to load the view, see detailed comments in the view dictionary class
        ///  
        /// 
        /// 
        /// 
        internal GeneratedView GetGeneratedView(EntitySetBase extent, MetadataWorkspace workspace) 
        {
            return this.m_viewDictionary.GetGeneratedView(extent, workspace, this); 
        } 

        ///  
        /// Attempts to find a mapping for the given function import.
        /// 
        /// Import declared in an entity container.
        /// Current workspace. 
        /// Returns target (store) function to which the import is mapped.
        /// true if a mapping is found; false otherwise 
        internal static bool TryGetFunctionImportTarget(EdmFunction functionImport, MetadataWorkspace workspace, out FunctionImportMapping targetFunction) 
        {
            Debug.Assert(null != functionImport); 
            Debug.Assert(null != workspace);
            // Retrieve entity container mappings
            ReadOnlyCollection entityContainerMaps =
                workspace.GetItems(DataSpace.CSSpace); 
            foreach (StorageEntityContainerMapping containerMapping in entityContainerMaps)
            { 
                if (containerMapping.TryGetFunctionImportMapping(functionImport, out targetFunction)) 
                {
                    return true; 
                }
            }
            targetFunction = null;
            return false; 
        }
 
        // Add to the cache. If it is already present, then throw an exception 
        private void AddInternal(StorageEntityContainerMapping storageMap)
        { 
            storageMap.DataSpace = DataSpace.CSSpace;
            try
            {
                base.AddInternal(storageMap); 
            }
            catch (ArgumentException e) 
            { 
                throw new MappingException(System.Data.Entity.Strings.Mapping_Duplicate_Type_1(
                    storageMap.EdmItem.Identity), e); 
            }
        }

        // Contains whether the given StorageEntityContainerName 
        internal bool ContainsStorageEntityContainer(string storageEntityContainerName)
        { 
            ReadOnlyCollection entityContainerMaps = 
                this.GetItems();
            return entityContainerMaps.Any(map => map.StorageEntityContainer.Name.Equals(storageEntityContainerName, StringComparison.Ordinal)); 
        }


        ///  
        /// This helper method loads items based on contents of in-memory XmlReader instances.
        /// Assumption: This method is called only from the constructor because m_extentMappingViews is not thread safe. 
        ///  
        /// A list of XmlReader instances
        /// A list of URIs 
        /// A list of schema errors
        private List LoadItems(IEnumerable xmlReaders,
                                        List mappingSchemaUris,
                                        Dictionary userDefinedQueryViewsDict, 
                                        Dictionary userDefinedQueryViewsOfTypeDict)
        { 
            Debug.Assert(m_memberMappings.Count == 0, "Assumption: This method is called only once, and from the constructor because m_extentMappingViews is not thread safe."); 

            List errors = new List(); 

            int index = -1;
            foreach (XmlReader xmlReader in xmlReaders)
            { 
                index++;
                string location = null; 
                if (mappingSchemaUris == null) 
                {
                    som.SchemaManager.TryGetBaseUri(xmlReader, out location); 
                }
                else
                {
                    location = mappingSchemaUris[index]; 
                }
 
                StorageMappingItemLoader mapLoader = new StorageMappingItemLoader( 
                                                            this,
                                                            location,  // ASSUMPTION: location is only used for generating error-messages 
                                                            m_memberMappings);

                IList schemaErrors = mapLoader.ParsingErrors;
                StorageEntityContainerMapping containerMapping = mapLoader.LoadMappingItems(xmlReader); 

                if (mapLoader.HasQueryViews && containerMapping != null) 
                { 
                    //Parse the query views so that we can report the errors in the user specified views
                    ViewDictionary.CollectViews(containerMapping, this, schemaErrors, userDefinedQueryViewsDict, userDefinedQueryViewsOfTypeDict); 
                }

                // Add container mapping if there are no errors and entity container mapping is not already present
                if (MetadataHelper.CheckIfAllErrorsAreWarnings(schemaErrors) && 
                    !this.Contains(containerMapping))
                { 
                    AddInternal(containerMapping); 
                }
                errors.AddRange(schemaErrors); 
            }

            CheckForDuplicateItems(EdmItemCollection, StoreItemCollection, errors);
 
            return errors;
        } 
 

        ///  
        /// Return the update view loader
        /// 
        /// 
        internal ViewLoader GetUpdateViewLoader() 
        {
            if (_viewLoader == null) 
            { 
                _viewLoader = new ViewLoader(this);
            } 

            return _viewLoader;
        }
 
        /// 
        /// this method will be called in metadatworkspace, the signature is the same as the one in ViewDictionary 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        internal bool TryGetGeneratedViewOfType(MetadataWorkspace workspace, EntitySetBase entity, EntityTypeBase type, bool includeSubtypes, out GeneratedView generatedView)
        { 
            return this.m_viewDictionary.TryGetGeneratedViewOfType(workspace, entity, type, includeSubtypes, out generatedView); 
        }
 
        // Check for duplicate items (items with same name) in edm item collection and store item collection. Mapping is the only logical place to do this.
        // The only other place is workspace, but that is at the time of registering item collections (only when the second one gets registered) and we
        // will have to throw exceptions at that time. If we do this check in mapping, we might throw error in a more consistent way (by adding it to error
        // collection). Also if someone is just creating item collection, and not registering it with workspace (tools), doing it in mapping makes more sense 
        private static void CheckForDuplicateItems(EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection, List errorCollection)
        { 
            Debug.Assert(edmItemCollection != null && storeItemCollection != null && errorCollection != null, "The parameters must not be null in CheckForDuplicateItems"); 

            foreach (GlobalItem item in edmItemCollection) 
            {
                if (storeItemCollection.Contains(item.Identity))
                {
                    errorCollection.Add(new EdmSchemaError(System.Data.Entity.Strings.Mapping_ItemWithSameNameExistsBothInCSpaceAndSSpace(item.Identity), 
                                        (int)StorageMappingErrorCode.ItemWithSameNameExistsBothInCSpaceAndSSpace, EdmSchemaErrorSeverity.Error));
                } 
            } 
        }
    }//---- ItemCollection 

}//----

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