MetadataWorkspace.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 / Metadata / MetadataWorkspace.cs / 5 / MetadataWorkspace.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....]
//--------------------------------------------------------------------- 
 
using System;
using System.Collections.Generic; 
using System.Collections.ObjectModel;
using System.Data;
using System.Data.Common.CommandTrees;
using System.Data.Mapping; 
using System.Data.Mapping.Update.Internal;
using System.Diagnostics; 
using System.Diagnostics.CodeAnalysis; 
using System.Text;
using System.Reflection; 
using System.Data.Mapping.ViewGeneration;
using System.Data.Entity;
using System.Linq;
using System.Data.Common.Utils; 
using System.Xml;
 
namespace System.Data.Metadata.Edm 
{
    ///  
    /// Runtime Metadata Workspace
    /// 
    public sealed class MetadataWorkspace
    { 
        #region Constructors
        ///  
        /// Constructs the new instance of runtime metadata workspace 
        /// 
        public MetadataWorkspace() 
        {
        }

        ///  
        /// Create MetadataWorkspace that is populated with ItemCollections for all the spaces that the metadata artifacts provided.
        /// All res:// paths will be resolved only from the assemblies returned from the enumerable assembliesToConsider. 
        ///  
        /// The paths where the metadata artifacts located
        /// User specified assemlies to consider 
        /// 
        /// Throw when assembliesToConsider is empty or contains null, or cannot find the corresponding assemly in it
        /// 
        public MetadataWorkspace(IEnumerable paths, IEnumerable assembliesToConsider) 
        {
            EntityUtil.CheckArgumentNull(paths, "paths"); 
            // we are intentionally not checking to see if the paths enumerable is empty 
            EntityUtil.CheckArgumentContainsNull(ref assembliesToConsider, "assembliesToConsider");
 
            Func resolveReference = (AssemblyName referenceName)=>
            {
                foreach(Assembly assembly in assembliesToConsider)
                { 
                    if (AssemblyName.ReferenceMatchesDefinition(referenceName, assembly.GetName()))
                    { 
                        return assembly; 
                    }
                } 
                throw EntityUtil.Argument(Strings.AssemblyMissingFromAssembliesToConsider(referenceName.FullName), "assembliesToConsider");
            };

 
            CreateMetadataWorkspaceWithResolver(paths, () => assembliesToConsider, resolveReference);
        } 
 
        private void CreateMetadataWorkspaceWithResolver(IEnumerable paths, Func> wildcardAssemblies, Func resolveReference)
        { 
            EntityUtil.CheckArgumentNull(paths, "paths");
            // we are intentionally not checking to see if the paths enumerable is empty
            EntityUtil.CheckArgumentNull(wildcardAssemblies, "wildcardAssemblies");
            EntityUtil.CheckArgumentNull(resolveReference, "resolveReference"); 

            MetadataArtifactLoader composite = MetadataArtifactLoader.CreateCompositeFromFilePaths(paths.ToArray(), "", new CustomAssemblyResolver(wildcardAssemblies, resolveReference)); 
 
            // only create the ItemCollection that has corresponding artifacts
            DataSpace dataSpace = DataSpace.CSpace; 
            using (DisposableCollectionWrapper cSpaceReaders = new DisposableCollectionWrapper(composite.CreateReaders(dataSpace)))
            {
                if (cSpaceReaders.Any())
                { 
                    this._itemsCSpace = new EdmItemCollection(cSpaceReaders, composite.GetPaths(dataSpace));
                } 
            } 

            dataSpace = DataSpace.SSpace; 
            using (DisposableCollectionWrapper sSpaceReaders = new DisposableCollectionWrapper(composite.CreateReaders(dataSpace)))
            {
                if (sSpaceReaders.Any())
                { 
                    this._itemsSSpace = new StoreItemCollection(sSpaceReaders, composite.GetPaths(dataSpace));
                } 
            } 

            dataSpace = DataSpace.CSSpace; 
            using (DisposableCollectionWrapper csSpaceReaders = new DisposableCollectionWrapper(composite.CreateReaders(dataSpace)))
            {
                if (csSpaceReaders.Any() && null != this._itemsCSpace && null != this._itemsSSpace)
                { 
                    this._itemsCSSpace = new StorageMappingItemCollection(this._itemsCSpace, this._itemsSSpace, csSpaceReaders, composite.GetPaths(dataSpace));
                } 
            } 
        }
        #endregion 

        #region Fields
        private EdmItemCollection _itemsCSpace;
        private StoreItemCollection _itemsSSpace; 
        private ObjectItemCollection _itemsOSpace;
        private StorageMappingItemCollection _itemsCSSpace; 
        private DefaultObjectMappingItemCollection _itemsOCSpace; 

        private List _cacheTokens; 

        #endregion

        #region public static Fields 
        //The Max EDM version thats going to be supported by the runtime.
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")] 
        public static readonly double MaximumEdmVersionSupported = 1.0; 
        #endregion
 
        #region Methods
        /// 
        /// Get item collection for the space. The ItemCollection is in read only mode as it is
        /// part of the workspace. 
        /// 
        /// The dataspace for the item colelction that should be returned 
        /// The item collection for the given space 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in 
        public ItemCollection GetItemCollection(DataSpace dataSpace)
        {
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return collection; 
        }
 
        ///  
        /// Register the item collection for the space associated with it.
        /// This should be done only once for a space. 
        /// If a space already has a registered ItemCollection InvalidOperation exception is thrown
        /// 
        /// The out parameter collection that needs to be filled up
        ///  
        /// if collection argument is null
        /// If there is an ItemCollection that has already been registered for collection's space passed in 
        public void RegisterItemCollection(ItemCollection collection) 
        {
            EntityUtil.CheckArgumentNull(collection, "collection"); 

            ItemCollection existing;
            try
            { 
                switch (collection.DataSpace)
                { 
                case DataSpace.CSpace: 
                    if (null == (existing = _itemsCSpace)) {
                        EdmItemCollection edmCollection = (EdmItemCollection)collection; 
                        if(edmCollection.EdmVersion > MetadataWorkspace.MaximumEdmVersionSupported)
                        {

                            throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EdmVersionNotSupportedByRuntime(edmCollection.EdmVersion, MaximumEdmVersionSupported)); 
                        }
                        _itemsCSpace = edmCollection; 
                    } 
                    break;
                case DataSpace.SSpace: 
                    if (null == (existing = _itemsSSpace))
                    {
                        _itemsSSpace = (StoreItemCollection)collection;
                    } 
                    break;
                case DataSpace.OSpace: 
                    if (null == (existing = _itemsOSpace)) { 
                        _itemsOSpace = (ObjectItemCollection)collection;
                    } 
                    break;
                case DataSpace.CSSpace:
                    if (null == (existing = _itemsCSSpace)) {
                        _itemsCSSpace = (StorageMappingItemCollection)collection; 
                    }
                    break; 
                default: 
                    Debug.Assert(collection.DataSpace == DataSpace.OCSpace, "Invalid DataSpace Enum value: " + collection.DataSpace);
 
                    if (null == (existing = _itemsOCSpace)) {
                        _itemsOCSpace = (DefaultObjectMappingItemCollection)collection;
                    }
                    break; 
                }
            } 
            catch (InvalidCastException) 
            {
                throw EntityUtil.InvalidCollectionForMapping(collection.DataSpace); 
            }
            if (null != existing)
            {
                throw EntityUtil.ItemCollectionAlreadyRegistered(collection.DataSpace); 
            }
            // Need to make sure that if the storage mapping Item collection was created with the 
            // same instances of item collection that are registered for CSpace and SSpace 
            if (collection.DataSpace == DataSpace.CSpace)
            { 
                if (_itemsCSSpace != null && !object.ReferenceEquals(_itemsCSSpace.EdmItemCollection, collection))
                {
                    throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
                } 
            }
 
            if (collection.DataSpace == DataSpace.SSpace) 
            {
                if (_itemsCSSpace != null && !object.ReferenceEquals(_itemsCSSpace.StoreItemCollection, collection)) 
                {
                    throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
                }
            } 

            if (collection.DataSpace == DataSpace.CSSpace) 
            { 
                if (_itemsCSpace != null && !object.ReferenceEquals(_itemsCSSpace.EdmItemCollection, _itemsCSpace))
                { 
                    throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
                }

                if (_itemsSSpace != null && !object.ReferenceEquals(_itemsCSSpace.StoreItemCollection, _itemsSSpace)) 
                {
                    throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace); 
                } 
            }
        } 

        /// 
        /// Add a token for this MetadataWorkspace just so this metadata workspace holds a reference to it, this
        /// is for metadata caching to make the workspace marking a particular cache entry is still in used 
        /// 
        ///  
        internal void AddMetadataEntryToken(object token) 
        {
            if (_cacheTokens == null) 
            {
                _cacheTokens = new List();
            }
 
            _cacheTokens.Add(token);
        } 
 
        /// 
        /// Load metadata from the given assembly 
        /// 
        /// The assembly from which to load metadata
        /// thrown if assembly argument is null
        public void LoadFromAssembly(Assembly assembly) 
        {
            EntityUtil.CheckArgumentNull(assembly, "assembly"); 
            ObjectItemCollection collection = (ObjectItemCollection)GetItemCollection(DataSpace.OSpace); 
            collection.LoadFromAssembly(assembly);
        } 

        /// 
        /// Load metadata from the type's assembly into the OSpace ItemCollection.
        /// If type comes from known source, has Ecma or Microsoft PublicKeyToken then the type's assembly is not 
        /// loaded, but the callingAssembly and its referenced assemblies are loaded.
        ///  
        /// The type's assembly is loaded into the OSpace ItemCollection 
        /// The assembly and its referenced assemblies to load when type is insuffiecent
        internal void LoadAssemblyForType(Type type, Assembly callingAssembly) 
        {
            // this exists separately from LoadFromAssembly so that we can handle generics, like IEnumerable
            Debug.Assert(null != type, "null type");
            ItemCollection collection; 
            if (TryGetItemCollection(DataSpace.OSpace, out collection))
            {   // if OSpace is not loaded - don't register 
                ObjectItemCollection objItemCollection = (ObjectItemCollection)collection; 
                if (!objItemCollection.LoadAssemblyForType(type) && (null != callingAssembly))
                { 
                    // only load from callingAssembly if all types were filtered
                    // then loaded referenced assemblies of calling assembly

                    // attempt automatic discovery of user types 
                    // interesting code paths are ObjectQuery, ObjectQuery, ObjectQuery
                    // other interesting code paths are ObjectQuery>, ObjectQuery> 
                    // when assemblies is mscorlib, System.Data or System.Data.Entity 
                    objItemCollection.LoadAllReferencedAssemblies(callingAssembly);
                } 
            }
        }

        ///  
        /// If OSpace is not loaded for the specified EntityType
        /// the load metadata from the callingAssembly and its referenced assemblies. 
        ///  
        /// The CSPace type to verify its OSpace counterpart is loaded
        /// The assembly and its referenced assemblies to load when type is insuffiecent 
        internal void LoadFromEntityType(EntityType type, Assembly callingAssembly)
        {
           // used by ObjectContext.*GetObjectByKey when the clr type is not available
           // so we check the OCMap to find the clr type else attempt to autoload the OSpace from callingAssembly 
            Debug.Assert(null != type, "null type");
            Map map; 
            if (!TryGetMap(type, DataSpace.OCSpace, out map)) 
            {   // an OCMap is not exist, attempt to load OSpace to retry
                LoadAssemblyForType(typeof(System.Data.Objects.DataClasses.IEntityWithKey), callingAssembly); 
            }
        }

        ///  
        /// Search for an item with the given identity in the given space.
        /// For example, The identity for EdmType is Namespace.Name. 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in 
        /// if identity argument passed in is null
        /// If the ItemCollection for this space does not have an item with the given identity 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace 
        public T GetItem(string identity, DataSpace dataSpace) where T:GlobalItem
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return collection.GetItem(identity, false /*ignoreCase*/);
        }
 
        /// 
        /// Search for an item with the given identity in the given space. 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        /// if identity or space argument is null 
        public bool TryGetItem(string identity, DataSpace space, out T item ) where T:GlobalItem
        { 
            item = null; 
            ItemCollection collection = GetItemCollection(space, false);
            return (null != collection) && collection.TryGetItem(identity, false /*ignoreCase*/, out item); 
        }

        /// 
        /// Search for an item with the given identity in the given space. 
        /// For example, The identity for EdmType is Namespace.Name.
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in 
        /// if identity argument passed in is null
        /// If the ItemCollection for this space does not have an item with the given identity 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace 
        public T GetItem(string identity, bool ignoreCase, DataSpace dataSpace) where T : GlobalItem
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return collection.GetItem(identity, ignoreCase);
        }
 
        /// 
        /// Search for an item with the given identity in the given space. 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        /// if identity or space argument is null
        public bool TryGetItem(string identity, bool ignoreCase, DataSpace dataSpace, out T item) where T : GlobalItem 
        { 
            item = null;
            ItemCollection collection = GetItemCollection(dataSpace, false); 
            return (null != collection) && collection.TryGetItem(identity, ignoreCase, out item);
        }

        ///  
        /// Returns ReadOnlyCollection of the Items of the given type
        /// in the workspace. 
        ///  
        /// 
        ///  
        /// 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace 
        public ReadOnlyCollection GetItems(DataSpace dataSpace) where T : GlobalItem
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true); 
            return collection.GetItems();
        } 

        /// 
        /// Search for a type metadata with the specified name and namespace name in the given space.
        ///  
        /// name of the type
        /// namespace of the type 
        /// Dataspace to search the type for 
        /// Returns null if no match found.
        /// if space argument is null 
        /// If ItemCollection has not been registered for the space passed in
        /// if name or namespaceName arguments passed in are null
        /// If the ItemCollection for this space does not have a type with the given name and namespaceName
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace 
        public EdmType GetType(string name, string namespaceName, DataSpace dataSpace)
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true); 
            return collection.GetType(name, namespaceName, false /*ignoreCase*/);
        } 

        /// 
        /// Search for a type metadata with the specified name and namespace name in the given space.
        ///  
        /// name of the type
        /// namespace of the type 
        /// Dataspace to search the type for 
        /// The type that needs to be filled with the return value
        /// Returns false if no match found. 
        /// if name, namespaceName or space argument is null
        public bool TryGetType(string name, string namespaceName, DataSpace dataSpace, out EdmType type)
        {
            type = null; 
            ItemCollection collection = GetItemCollection(dataSpace, false);
            return (null != collection) && collection.TryGetType(name, namespaceName, false /*ignoreCase*/, out type); 
        } 

 

        /// 
        /// Search for a type metadata with the specified name and namespace name in the given space.
        ///  
        /// name of the type
        /// namespace of the type 
        ///  
        /// Dataspace to search the type for
        /// Returns null if no match found. 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in
        /// if name or namespaceName arguments passed in are null
        /// If the ItemCollection for this space does not have a type with the given name and namespaceName 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
        public EdmType GetType(string name, string namespaceName, bool ignoreCase, DataSpace dataSpace) 
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return collection.GetType(name, namespaceName, ignoreCase); 
        }

        /// 
        /// Search for a type metadata with the specified name and namespace name in the given space. 
        /// 
        /// name of the type 
        /// namespace of the type 
        /// Dataspace to search the type for
        ///  
        /// The type that needs to be filled with the return value
        /// Returns null if no match found.
        /// if name, namespaceName or space argument is null
        public bool TryGetType(string name, string namespaceName, bool ignoreCase, 
                               DataSpace dataSpace, out EdmType type)
        { 
            type = null; 
            ItemCollection collection = GetItemCollection(dataSpace, false);
            return (null != collection) && collection.TryGetType(name, namespaceName, ignoreCase, out type); 
        }


        ///  
        /// Get an entity container based upon the strong name of the container
        /// If no entity container is found, returns null, else returns the first one///  
        /// name of the entity container 
        /// 
        /// The EntityContainer 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in
        /// if name argument passed in is null
        /// If the ItemCollection for this space does not have a EntityContainer with the given name 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
        public EntityContainer GetEntityContainer(string name, DataSpace dataSpace) 
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return collection.GetEntityContainer(name); 
        }

        /// 
        /// Get an entity container based upon the strong name of the container 
        /// If no entity container is found, returns null, else returns the first one/// 
        /// name of the entity container 
        ///  
        /// 
        /// if either space or name arguments is null 
        public bool TryGetEntityContainer(string name, DataSpace dataSpace, out EntityContainer entityContainer)
        {
            entityContainer = null;
            // null check exists in call stack, but throws for "identity" not "name" 
            EntityUtil.GenericCheckArgumentNull(name, "name");
            ItemCollection collection = GetItemCollection(dataSpace, false); 
            return (null != collection) && collection.TryGetEntityContainer(name, out entityContainer); 
        }
 
        /// 
        /// Get an entity container based upon the strong name of the container
        /// If no entity container is found, returns null, else returns the first one/// 
        /// name of the entity container 
        /// true for case-insensitive lookup
        ///  
        /// The EntityContainer 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in 
        /// if name argument passed in is null
        /// If the ItemCollection for this space does not have a EntityContainer with the given name
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
        public EntityContainer GetEntityContainer(string name, bool ignoreCase, DataSpace dataSpace) 
        {
            ItemCollection collection = GetItemCollection(dataSpace, true); 
            return collection.GetEntityContainer(name, ignoreCase); 
        }
 
        /// 
        /// Get an entity container based upon the strong name of the container
        /// If no entity container is found, returns null, else returns the first one/// 
        /// name of the entity container 
        /// true for case-insensitive lookup
        ///  
        ///  
        /// if name or space argument is null
        public bool TryGetEntityContainer(string name, bool ignoreCase, 
                                                             DataSpace dataSpace, out EntityContainer entityContainer)
        {
            entityContainer = null;
            // null check exists in call stack, but throws for "identity" not "name" 
            EntityUtil.GenericCheckArgumentNull(name, "name");
            ItemCollection collection = GetItemCollection(dataSpace, false); 
            return (null != collection) && collection.TryGetEntityContainer(name, ignoreCase, out entityContainer); 
        }
 
        /// 
        /// Get all the overloads of the function with the given name
        /// 
        /// name of the function 
        /// namespace of the function
        /// The dataspace for which we need to get the function for 
        /// A collection of all the functions with the given name in the given data space 
        /// if space argument is null
        /// if name or namespaceName argument is null 
        /// If ItemCollection has not been registered for the space passed in
        /// if functionName argument passed in is null
        /// If the ItemCollection for this space does not have a EdmFunction with the given functionName
        /// If the name or namespaceName is empty 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
        public ReadOnlyCollection GetFunctions(string name, string namespaceName, DataSpace dataSpace) 
        { 
            return GetFunctions(name, namespaceName, dataSpace, false /*ignoreCase*/);
        } 

        /// 
        /// Get all the overloads of the function with the given name
        ///  
        /// name of the function
        /// namespace of the function 
        /// The dataspace for which we need to get the function for 
        /// true for case-insensitive lookup
        /// A collection of all the functions with the given name in the given data space 
        /// if space argument is null
        /// if name or namespaceName argument is null
        /// If ItemCollection has not been registered for the space passed in
        /// if functionName argument passed in is null 
        /// If the ItemCollection for this space does not have a EdmFunction with the given functionName
        /// If the name or namespaceName is empty 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace 
        public ReadOnlyCollection GetFunctions(string name,
                                                            string namespaceName, 
                                                            DataSpace dataSpace,
                                                            bool ignoreCase)
        {
            EntityUtil.CheckStringArgument(name, "name"); 
            EntityUtil.CheckStringArgument(namespaceName, "namespaceName");
            ItemCollection collection = GetItemCollection(dataSpace, true); 
 
            // Get the function with this full name, which is namespace name plus name
            return collection.GetFunctions(namespaceName + "." + name, ignoreCase); 
        }

        /// 
        /// Gets the function as specified by the function key 
        /// 
        /// name of the function 
        /// namespace of the function 
        /// types of the parameters
        /// true for case-insensitive lookup 
        /// 
        /// The function that needs to be returned
        ///  The function as specified in the function key or null
        /// if name, namespaceName, parameterTypes or space argument is null 
        internal bool TryGetFunction(string name,
                                   string namespaceName, 
                                   TypeUsage[] parameterTypes, 
                                   bool ignoreCase,
                                   DataSpace dataSpace, 
                                   out EdmFunction function)
        {
            function = null;
            EntityUtil.GenericCheckArgumentNull(name, "name"); 
            EntityUtil.GenericCheckArgumentNull(namespaceName, "namespaceName");
            ItemCollection collection = GetItemCollection(dataSpace, false); 
 
            // Get the function with this full name, which is namespace name plus name
            return (null != collection) && collection.TryGetFunction(namespaceName + "." + name, parameterTypes, ignoreCase, out function); 
        }

        /// 
        /// Get the list of primitive types for the given space 
        /// 
        /// dataspace for which you need the list of primitive types 
        ///  
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
        public ReadOnlyCollection GetPrimitiveTypes(DataSpace dataSpace)
        {
            ItemCollection collection = GetItemCollection(dataSpace, true); 
            return collection.GetItems();
        } 
 
        /// 
        /// Get all the items in the data space 
        /// 
        /// dataspace for which you need the list of items
        /// 
        /// if space argument is null 
        /// If ItemCollection has not been registered for the space passed in
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace 
        public ReadOnlyCollection GetItems(DataSpace dataSpace) 
        {
            ItemCollection collection = GetItemCollection(dataSpace, true); 
            return collection.GetItems();
        }

        ///  
        /// Given the canonical primitive type, get the mapping primitive type in the given dataspace
        ///  
        /// primitive type kind 
        /// dataspace in which one needs to the mapping primitive types
        /// The mapped scalar type 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
        internal PrimitiveType GetMappedPrimitiveType(PrimitiveTypeKind primitiveTypeKind, DataSpace dataSpace) 
        {
            ItemCollection collection = GetItemCollection(dataSpace, true); 
            return collection.GetMappedPrimitiveType(primitiveTypeKind); 
        }
 
        /// 
        /// Search for a Mapping metadata with the specified type key.
        /// 
        /// type 
        /// The dataspace that the type for which map needs to be returned belongs to
        /// true for case-insensitive lookup 
        /// space for which you want to get the mapped type 
        /// 
        /// Returns false if no match found. 
        internal bool TryGetMap(string typeIdentity, DataSpace typeSpace, bool ignoreCase, DataSpace mappingSpace, out Map map)
        {
            map = null;
            ItemCollection collection = GetItemCollection(mappingSpace, false); 
            return (null != collection) && ((MappingItemCollection)collection).TryGetMap(typeIdentity, typeSpace, ignoreCase, out map);
        } 
 
        /// 
        /// Search for a Mapping metadata with the specified type key. 
        /// 
        /// typeIdentity of the type
        /// The dataspace that the type for which map needs to be returned belongs to
        /// space for which you want to get the mapped type 
        ///  Thrown if mapping space is not valid
        internal Map GetMap(string identity, DataSpace typeSpace, DataSpace dataSpace) 
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return ((MappingItemCollection)collection).GetMap(identity, typeSpace); 
        }

        /// 
        /// Search for a Mapping metadata with the specified type key. 
        /// 
        ///  
        /// space for which you want to get the mapped type 
        ///  Thrown if mapping space is not valid
        internal Map GetMap(GlobalItem item, DataSpace dataSpace) 
        {
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return ((MappingItemCollection)collection).GetMap(item);
        } 

        ///  
        /// Search for a Mapping metadata with the specified type key. 
        /// 
        ///  
        /// space for which you want to get the mapped type
        /// 
        /// Returns false if no match found.
        internal bool TryGetMap(GlobalItem item, DataSpace dataSpace, out Map map) 
        {
            map = null; 
            ItemCollection collection = GetItemCollection(dataSpace, false); 
            return (null != collection) && ((MappingItemCollection)collection).TryGetMap(item, out map);
        } 

        private ItemCollection RegisterDefaultObjectMappingItemCollection()
        {
            EdmItemCollection edm = _itemsCSpace as EdmItemCollection; 
            ObjectItemCollection obj = _itemsOSpace as ObjectItemCollection;
            if ((null != edm) && (null != obj)) 
            { 
                RegisterItemCollection(new DefaultObjectMappingItemCollection(edm, obj));
            } 
            return _itemsOCSpace;
        }

        ///  
        /// Get item collection for the space, if registered. If returned, the ItemCollection is in read only mode as it is
        /// part of the workspace. 
        ///  
        /// The dataspace for the item collection that should be returned
        /// The collection registered for the specified dataspace, if any 
        /// true if an item collection is currently registered for the specified space; otherwise false.
        /// if space argument is null
        public bool TryGetItemCollection(DataSpace dataSpace, out ItemCollection collection)
        { 
            collection = GetItemCollection(dataSpace, false);
            return (null != collection); 
        } 

        ///  
        /// Checks if the space is valid and whether the collection is registered for the given space, and if both are valid,
        /// then returns the itemcollection for the given space
        /// 
        ///  
        /// if true, will throw
        /// Thrown if required and mapping space is not valid or registered 
        internal ItemCollection GetItemCollection(DataSpace dataSpace, bool required) 
        {
            ItemCollection collection; 
            switch (dataSpace)
            {
            case DataSpace.CSpace:
                collection = _itemsCSpace; 
                break;
            case DataSpace.OSpace: 
                collection = _itemsOSpace; 
                break;
            case DataSpace.OCSpace: 
                collection = _itemsOCSpace ?? RegisterDefaultObjectMappingItemCollection();
                break;
            case DataSpace.CSSpace:
                collection = _itemsCSSpace; 
                break;
            case DataSpace.SSpace: 
                collection = _itemsSSpace; 
                break;
            default: 
                if (required) {
                    Debug.Fail("Invalid DataSpace Enum value: " + dataSpace);
                }
                collection = null; 
                break;
            } 
            if (required && (null == collection)) { 
                throw EntityUtil.NoCollectionForSpace(dataSpace);
            } 
            return collection;
        }

        ///  
        /// The method returns the OSpace type mapped to the specified Edm Space Type.
        /// If the DataSpace of the argument is not CSpace, or the mapped OSpace type 
        /// cannot be determined, an ArgumentException is thrown. 
        /// 
        /// The CSpace type to look up 
        /// The OSpace type mapped to the supplied argument
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
        public StructuralType GetObjectSpaceType(StructuralType edmSpaceType)
        { 
            StructuralType objectSpaceType;
            if (!this.TryGetObjectSpaceType(edmSpaceType, out objectSpaceType)) 
            { 
                throw EntityUtil.Argument(Strings.FailedToFindOSpaceTypeMapping(edmSpaceType.Identity));
            } 

            return objectSpaceType;
        }
 
        /// 
        /// This method returns the OSpace type mapped to the specified Edm Space Type. 
        /// If the DataSpace of the argument is not CSpace, or if the mapped OSpace type 
        /// cannot be determined, the method returns false and sets the out parameter
        /// to null. 
        /// 
        /// The CSpace type to look up
        /// The OSpace type mapped to the supplied argument
        /// true on success, false on failure 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
        public bool TryGetObjectSpaceType(StructuralType edmSpaceType, out StructuralType objectSpaceType) 
        { 
            EntityUtil.CheckArgumentNull(edmSpaceType, "edmSpaceType");
 
            if (edmSpaceType.DataSpace != DataSpace.CSpace)
            {
                throw EntityUtil.Argument(Strings.ArgumentMustBeCSpaceType, "edmSpaceType");
            } 

            objectSpaceType = null; 
 
            Map map;
            if (!this.TryGetMap(edmSpaceType, DataSpace.OCSpace, out map)) 
            {
                return false;
            }
 
            ObjectTypeMapping ocMap = map as ObjectTypeMapping;
            if (ocMap == null) 
            { 
                return false;
            } 

            objectSpaceType = (StructuralType)ocMap.ClrType;
            return true;
        } 

        ///  
        /// This method returns the Edm Space type mapped to the OSpace Type parameter. If the 
        /// DataSpace of the supplied type is not OSpace, or the mapped Edm Space type cannot
        /// be determined, an ArgumentException is thrown. 
        /// 
        /// The OSpace type to look up
        /// The CSpace type mapped to the OSpace parameter
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")] 
        public StructuralType GetEdmSpaceType(StructuralType objectSpaceType)
        { 
            StructuralType edmSpaceType; 
            if (!this.TryGetEdmSpaceType(objectSpaceType, out edmSpaceType))
            { 
                throw EntityUtil.Argument(Strings.FailedToFindCSpaceTypeMapping(objectSpaceType.Identity));
            }

            return edmSpaceType; 
        }
 
        ///  
        /// This method returns the Edm Space type mapped to the OSpace Type parameter. If the
        /// DataSpace of the supplied type is not OSpace, or the mapped Edm Space type cannot 
        /// be determined, the method returns false and sets the out parameter to null.
        /// 
        /// The OSpace type to look up
        /// The mapped CSpace type 
        /// true on success, false on failure
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")] 
        public bool TryGetEdmSpaceType(StructuralType objectSpaceType, out StructuralType edmSpaceType) 
        {
            EntityUtil.CheckArgumentNull(objectSpaceType, "objectSpaceType"); 

            if (objectSpaceType.DataSpace != DataSpace.OSpace)
            {
                throw EntityUtil.Argument(Strings.ArgumentMustBeOSpaceType, "objectSpaceType"); 
            }
 
            edmSpaceType = null; 

            Map map; 
            if (!this.TryGetMap(objectSpaceType, DataSpace.OCSpace, out map))
            {
                return false;
            } 

            ObjectTypeMapping ocMap = map as ObjectTypeMapping; 
            if (ocMap == null) 
            {
                return false; 
            }

            edmSpaceType = (StructuralType)ocMap.EdmType;
            return true; 
        }
 
        /////  
        ///// Returns the update or query view for an Extent as a
        ///// command tree. For a given Extent, MetadataWorkspace will 
        ///// have either a Query view or an Update view but not both.
        ///// 
        ///// 
        /////  
        internal DbQueryCommandTree GetCqtView(EntitySetBase extent)
        { 
            return GetGeneratedView(extent).GetCommandTree(this); 
        }
 
        /// 
        /// Returns generated update or query view for the given extent.
        /// 
        internal GeneratedView GetGeneratedView(EntitySetBase extent) 
        {
            ItemCollection collection = GetItemCollection(DataSpace.CSSpace, true); 
            return ((StorageMappingItemCollection)collection).GetGeneratedView(extent, this); 
        }
 
        /// 
        /// Returns a TypeOf/TypeOfOnly Query for a given Extent and Type as a command tree.
        /// 
        ///  
        /// 
        internal bool TryGetGeneratedViewOfType(EntitySetBase extent, EntityTypeBase type, bool includeSubtypes, out GeneratedView generatedView) 
        { 
            ItemCollection collection = GetItemCollection(DataSpace.CSSpace, true);
            return ((StorageMappingItemCollection)collection).TryGetGeneratedViewOfType(this, extent, type, includeSubtypes, out generatedView); 
        }

        /// 
        /// Determines if a target function exists for the given function import. 
        /// 
        /// Function import (function declared in model entity container) 
        /// Function target mapping (function to which the import is mapped in the target store) 
        /// true if a mapped target function exists; false otherwise
        internal bool TryGetFunctionImportMapping(EdmFunction functionImport, out FunctionImportMapping targetFunctionMapping) 
        {
            ItemCollection collection = GetItemCollection(DataSpace.CSSpace, true);
            return StorageMappingItemCollection.TryGetFunctionImportTarget(functionImport, this, out targetFunctionMapping);
        } 

        ///  
        /// Returns the view loader associated with this workspace, 
        /// creating a loader if non exists. The loader includes
        /// context information used by the update pipeline when 
        /// processing changes to C-space extents.
        /// 
        /// 
        internal ViewLoader GetUpdateViewLoader() 
        {
            if (_itemsCSSpace != null) 
            { 
                return _itemsCSSpace.GetUpdateViewLoader();
            } 
            return null;
        }

 
        /// 
        /// Takes in a Edm space type usage and converts into an 
        /// equivalent O space type usage 
        /// 
        ///  
        /// 
        internal TypeUsage GetOSpaceTypeUsage(TypeUsage edmSpaceTypeUsage)
        {
            EntityUtil.CheckArgumentNull(edmSpaceTypeUsage, "edmSpaceTypeUsage"); 
            if (edmSpaceTypeUsage.EdmType == null)
            { 
                throw EntityUtil.TypeUsageHasNoEdmType("edmSpaceTypeUsage"); 
            }
 
            EdmType clrType = null;
            if (Helper.IsPrimitiveType(edmSpaceTypeUsage.EdmType))
            {
                ItemCollection collection = GetItemCollection(DataSpace.OSpace, true); 
                clrType = collection.GetMappedPrimitiveType(((PrimitiveType)edmSpaceTypeUsage.EdmType).PrimitiveTypeKind);
            } 
            else 
            {
                // Check and throw if the OC space doesn't exist 
                ItemCollection collection = GetItemCollection(DataSpace.OCSpace, true);

                // Get the OC map
                Map map = ((DefaultObjectMappingItemCollection)collection).GetMap(edmSpaceTypeUsage.EdmType); 
                clrType = ((ObjectTypeMapping)map).ClrType;
            } 
 
            Debug.Assert(!Helper.IsPrimitiveType(clrType) ||
                object.ReferenceEquals(ClrProviderManifest.Instance.GetFacetDescriptions(clrType), 
                                                EdmProviderManifest.Instance.GetFacetDescriptions(clrType.BaseType)),
                                                "these are no longer equal so we can't just use the same set of facets for the new type usage");

            // Transfer the facet values 
            TypeUsage result = TypeUsage.Create(clrType, edmSpaceTypeUsage.Facets);
 
            return result; 
        }
 
        /// 
        /// Returns true if the item collection for the given space has already been registered else returns false
        /// 
        ///  
        /// 
        internal bool IsItemCollectionAlreadyRegistered(DataSpace dataSpace) 
        { 
            ItemCollection itemCollection;
            return TryGetItemCollection(dataSpace, out itemCollection); 
        }

        /// 
        /// Requires: C, S and CS are registered in this and other 
        /// Determines whether C, S and CS are equivalent. Useful in determining whether a DbCommandTree
        /// is usable within a particular entity connection. 
        ///  
        /// Other workspace.
        /// true is C, S and CS collections are equivalent 
        internal bool IsMetadataWorkspaceCSCompatible(MetadataWorkspace other)
        {
            Debug.Assert(this.IsItemCollectionAlreadyRegistered(DataSpace.CSSpace) &&
                other.IsItemCollectionAlreadyRegistered(DataSpace.CSSpace), 
                "requires: C, S and CS are registered in this and other");
 
            bool result = this._itemsCSSpace.MetadataEquals(other._itemsCSSpace); 

            Debug.Assert(!result || 
                (this._itemsCSpace.MetadataEquals(other._itemsCSpace) && this._itemsSSpace.MetadataEquals(other._itemsSSpace)),
                "constraint: this.CS == other.CS --> this.S == other.S && this.C == other.C");

            return result; 
        }
 
        ///  
        /// Clear all the metadata cache entries
        ///  
        public static void ClearCache()
        {
            MetadataCache.Clear();
            ObjectItemCollection.ViewGenerationAssemblies.Clear(); 
        }
 
        ///  
        /// Creates a new Metadata workspace sharing the (currently defined) item collections
        /// and tokens for caching purposes. 
        /// 
        /// 
        internal MetadataWorkspace ShallowCopy()
        { 
            MetadataWorkspace copy = (MetadataWorkspace)MemberwiseClone();
            if (null != copy._cacheTokens) { 
                copy._cacheTokens = new List(copy._cacheTokens); 
            }
            return copy; 
        }

        /// 
        /// Returns the canonical Model TypeUsage for a given PrimitiveTypeKind 
        /// 
        /// PrimitiveTypeKind for which a canonical TypeUsage is expected 
        /// a canonical model TypeUsage 
        internal TypeUsage GetCanonicalModelTypeUsage(PrimitiveTypeKind primitiveTypeKind)
        { 
            return EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(primitiveTypeKind);
        }

        ///  
        /// Returns the Model PrimitiveType for a given primitiveTypeKind
        ///  
        /// a PrimitiveTypeKind for which a Model PrimitiveType is expected 
        /// Model PrimitiveType
        internal PrimitiveType GetModelPrimitiveType(PrimitiveTypeKind primitiveTypeKind) 
        {
            return EdmProviderManifest.Instance.GetPrimitiveType(primitiveTypeKind);
        }
 

        // 
        // Returns list of "interesting" members for the given EntitySet/EntityType 
        // Interesting Members are:
        //    0. Key members 
        //    1. Members with C-Side conditions (complex types can not have C-side condition at present)
        //    2. Members participating in association end
        //    3. Members with ConcurrencyMode 'Fixed'
        //      3.1 Complex Members with any child member having Concurrency mode Fixed 
        //    4. Members included in Update ModificationFunction with Version='Original' (Original = Not Current)
        //      4.1 Complex Members in ModificaionFunction if any sub-member is interesting 
        // 
        // Note: Key values are not returned because they are immutable and never "interesting"
        // Abstract EntityTypes are allowed since their parent attributes can be mapped differently. 
        /// 
        /// Returns members of a given EntitySet/EntityType for which original values are necessary for determining which tables to modify.
        /// 
        /// An EntitySet belonging to the C-Space 
        /// An EntityType that participates in the given EntitySet
        /// Edm Members for which original Value is required 
        public IEnumerable GetRequiredOriginalValueMembers(EntitySetBase entitySet, EntityTypeBase entityType) 
        {
            EntityUtil.CheckArgumentNull(entitySet, "entitySet"); 
            EntityUtil.CheckArgumentNull(entityType, "entityType");

            Debug.Assert(entitySet.EntityContainer != null);
 
            //Check that EntitySet is from CSpace
            if (entitySet.EntityContainer.GetDataSpace() != DataSpace.CSpace) 
            { 
                AssociationSet associationSet = entitySet as AssociationSet;
                if (associationSet != null) 
                {
                    throw EntityUtil.AssociationSetNotInCSpace(entitySet.Name);
                }
                else 
                {
                    throw EntityUtil.EntitySetNotInCSpace(entitySet.Name); 
                } 
            }
 
            //Check that entityType belongs to entitySet
            if (!entitySet.ElementType.IsAssignableFrom(entityType))
            {
                AssociationSet associationSet = entitySet as AssociationSet; 
                if (associationSet != null)
                { 
                    throw EntityUtil.TypeNotInAssociationSet(entitySet.Name, entitySet.ElementType.FullName, entityType.FullName); 
                }
                else 
                {
                    throw EntityUtil.TypeNotInEntitySet(entitySet.Name, entitySet.ElementType.FullName, entityType.FullName);
                }
            } 

            StorageMappingItemCollection mappingCollection = (StorageMappingItemCollection)GetItemCollection(DataSpace.CSSpace, true); 
            return mappingCollection.GetRequiredOriginalValueMembers(new Pair(entitySet, entityType)); 
        }
 
        #endregion

        #region Properties
        ///  
        /// Returns the QueryCacheManager hosted by this metadata workspace instance
        ///  
        internal System.Data.Common.QueryCache.QueryCacheManager GetQueryCacheManager() 
        {
            Debug.Assert(null != _itemsSSpace, "_itemsSSpace must not be null"); 
            return _itemsSSpace.QueryCacheManager;
        }
        #endregion
    } 
}

// 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.Data;
using System.Data.Common.CommandTrees;
using System.Data.Mapping; 
using System.Data.Mapping.Update.Internal;
using System.Diagnostics; 
using System.Diagnostics.CodeAnalysis; 
using System.Text;
using System.Reflection; 
using System.Data.Mapping.ViewGeneration;
using System.Data.Entity;
using System.Linq;
using System.Data.Common.Utils; 
using System.Xml;
 
namespace System.Data.Metadata.Edm 
{
    ///  
    /// Runtime Metadata Workspace
    /// 
    public sealed class MetadataWorkspace
    { 
        #region Constructors
        ///  
        /// Constructs the new instance of runtime metadata workspace 
        /// 
        public MetadataWorkspace() 
        {
        }

        ///  
        /// Create MetadataWorkspace that is populated with ItemCollections for all the spaces that the metadata artifacts provided.
        /// All res:// paths will be resolved only from the assemblies returned from the enumerable assembliesToConsider. 
        ///  
        /// The paths where the metadata artifacts located
        /// User specified assemlies to consider 
        /// 
        /// Throw when assembliesToConsider is empty or contains null, or cannot find the corresponding assemly in it
        /// 
        public MetadataWorkspace(IEnumerable paths, IEnumerable assembliesToConsider) 
        {
            EntityUtil.CheckArgumentNull(paths, "paths"); 
            // we are intentionally not checking to see if the paths enumerable is empty 
            EntityUtil.CheckArgumentContainsNull(ref assembliesToConsider, "assembliesToConsider");
 
            Func resolveReference = (AssemblyName referenceName)=>
            {
                foreach(Assembly assembly in assembliesToConsider)
                { 
                    if (AssemblyName.ReferenceMatchesDefinition(referenceName, assembly.GetName()))
                    { 
                        return assembly; 
                    }
                } 
                throw EntityUtil.Argument(Strings.AssemblyMissingFromAssembliesToConsider(referenceName.FullName), "assembliesToConsider");
            };

 
            CreateMetadataWorkspaceWithResolver(paths, () => assembliesToConsider, resolveReference);
        } 
 
        private void CreateMetadataWorkspaceWithResolver(IEnumerable paths, Func> wildcardAssemblies, Func resolveReference)
        { 
            EntityUtil.CheckArgumentNull(paths, "paths");
            // we are intentionally not checking to see if the paths enumerable is empty
            EntityUtil.CheckArgumentNull(wildcardAssemblies, "wildcardAssemblies");
            EntityUtil.CheckArgumentNull(resolveReference, "resolveReference"); 

            MetadataArtifactLoader composite = MetadataArtifactLoader.CreateCompositeFromFilePaths(paths.ToArray(), "", new CustomAssemblyResolver(wildcardAssemblies, resolveReference)); 
 
            // only create the ItemCollection that has corresponding artifacts
            DataSpace dataSpace = DataSpace.CSpace; 
            using (DisposableCollectionWrapper cSpaceReaders = new DisposableCollectionWrapper(composite.CreateReaders(dataSpace)))
            {
                if (cSpaceReaders.Any())
                { 
                    this._itemsCSpace = new EdmItemCollection(cSpaceReaders, composite.GetPaths(dataSpace));
                } 
            } 

            dataSpace = DataSpace.SSpace; 
            using (DisposableCollectionWrapper sSpaceReaders = new DisposableCollectionWrapper(composite.CreateReaders(dataSpace)))
            {
                if (sSpaceReaders.Any())
                { 
                    this._itemsSSpace = new StoreItemCollection(sSpaceReaders, composite.GetPaths(dataSpace));
                } 
            } 

            dataSpace = DataSpace.CSSpace; 
            using (DisposableCollectionWrapper csSpaceReaders = new DisposableCollectionWrapper(composite.CreateReaders(dataSpace)))
            {
                if (csSpaceReaders.Any() && null != this._itemsCSpace && null != this._itemsSSpace)
                { 
                    this._itemsCSSpace = new StorageMappingItemCollection(this._itemsCSpace, this._itemsSSpace, csSpaceReaders, composite.GetPaths(dataSpace));
                } 
            } 
        }
        #endregion 

        #region Fields
        private EdmItemCollection _itemsCSpace;
        private StoreItemCollection _itemsSSpace; 
        private ObjectItemCollection _itemsOSpace;
        private StorageMappingItemCollection _itemsCSSpace; 
        private DefaultObjectMappingItemCollection _itemsOCSpace; 

        private List _cacheTokens; 

        #endregion

        #region public static Fields 
        //The Max EDM version thats going to be supported by the runtime.
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")] 
        public static readonly double MaximumEdmVersionSupported = 1.0; 
        #endregion
 
        #region Methods
        /// 
        /// Get item collection for the space. The ItemCollection is in read only mode as it is
        /// part of the workspace. 
        /// 
        /// The dataspace for the item colelction that should be returned 
        /// The item collection for the given space 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in 
        public ItemCollection GetItemCollection(DataSpace dataSpace)
        {
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return collection; 
        }
 
        ///  
        /// Register the item collection for the space associated with it.
        /// This should be done only once for a space. 
        /// If a space already has a registered ItemCollection InvalidOperation exception is thrown
        /// 
        /// The out parameter collection that needs to be filled up
        ///  
        /// if collection argument is null
        /// If there is an ItemCollection that has already been registered for collection's space passed in 
        public void RegisterItemCollection(ItemCollection collection) 
        {
            EntityUtil.CheckArgumentNull(collection, "collection"); 

            ItemCollection existing;
            try
            { 
                switch (collection.DataSpace)
                { 
                case DataSpace.CSpace: 
                    if (null == (existing = _itemsCSpace)) {
                        EdmItemCollection edmCollection = (EdmItemCollection)collection; 
                        if(edmCollection.EdmVersion > MetadataWorkspace.MaximumEdmVersionSupported)
                        {

                            throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EdmVersionNotSupportedByRuntime(edmCollection.EdmVersion, MaximumEdmVersionSupported)); 
                        }
                        _itemsCSpace = edmCollection; 
                    } 
                    break;
                case DataSpace.SSpace: 
                    if (null == (existing = _itemsSSpace))
                    {
                        _itemsSSpace = (StoreItemCollection)collection;
                    } 
                    break;
                case DataSpace.OSpace: 
                    if (null == (existing = _itemsOSpace)) { 
                        _itemsOSpace = (ObjectItemCollection)collection;
                    } 
                    break;
                case DataSpace.CSSpace:
                    if (null == (existing = _itemsCSSpace)) {
                        _itemsCSSpace = (StorageMappingItemCollection)collection; 
                    }
                    break; 
                default: 
                    Debug.Assert(collection.DataSpace == DataSpace.OCSpace, "Invalid DataSpace Enum value: " + collection.DataSpace);
 
                    if (null == (existing = _itemsOCSpace)) {
                        _itemsOCSpace = (DefaultObjectMappingItemCollection)collection;
                    }
                    break; 
                }
            } 
            catch (InvalidCastException) 
            {
                throw EntityUtil.InvalidCollectionForMapping(collection.DataSpace); 
            }
            if (null != existing)
            {
                throw EntityUtil.ItemCollectionAlreadyRegistered(collection.DataSpace); 
            }
            // Need to make sure that if the storage mapping Item collection was created with the 
            // same instances of item collection that are registered for CSpace and SSpace 
            if (collection.DataSpace == DataSpace.CSpace)
            { 
                if (_itemsCSSpace != null && !object.ReferenceEquals(_itemsCSSpace.EdmItemCollection, collection))
                {
                    throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
                } 
            }
 
            if (collection.DataSpace == DataSpace.SSpace) 
            {
                if (_itemsCSSpace != null && !object.ReferenceEquals(_itemsCSSpace.StoreItemCollection, collection)) 
                {
                    throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
                }
            } 

            if (collection.DataSpace == DataSpace.CSSpace) 
            { 
                if (_itemsCSpace != null && !object.ReferenceEquals(_itemsCSSpace.EdmItemCollection, _itemsCSpace))
                { 
                    throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace);
                }

                if (_itemsSSpace != null && !object.ReferenceEquals(_itemsCSSpace.StoreItemCollection, _itemsSSpace)) 
                {
                    throw EntityUtil.InvalidCollectionSpecified(collection.DataSpace); 
                } 
            }
        } 

        /// 
        /// Add a token for this MetadataWorkspace just so this metadata workspace holds a reference to it, this
        /// is for metadata caching to make the workspace marking a particular cache entry is still in used 
        /// 
        ///  
        internal void AddMetadataEntryToken(object token) 
        {
            if (_cacheTokens == null) 
            {
                _cacheTokens = new List();
            }
 
            _cacheTokens.Add(token);
        } 
 
        /// 
        /// Load metadata from the given assembly 
        /// 
        /// The assembly from which to load metadata
        /// thrown if assembly argument is null
        public void LoadFromAssembly(Assembly assembly) 
        {
            EntityUtil.CheckArgumentNull(assembly, "assembly"); 
            ObjectItemCollection collection = (ObjectItemCollection)GetItemCollection(DataSpace.OSpace); 
            collection.LoadFromAssembly(assembly);
        } 

        /// 
        /// Load metadata from the type's assembly into the OSpace ItemCollection.
        /// If type comes from known source, has Ecma or Microsoft PublicKeyToken then the type's assembly is not 
        /// loaded, but the callingAssembly and its referenced assemblies are loaded.
        ///  
        /// The type's assembly is loaded into the OSpace ItemCollection 
        /// The assembly and its referenced assemblies to load when type is insuffiecent
        internal void LoadAssemblyForType(Type type, Assembly callingAssembly) 
        {
            // this exists separately from LoadFromAssembly so that we can handle generics, like IEnumerable
            Debug.Assert(null != type, "null type");
            ItemCollection collection; 
            if (TryGetItemCollection(DataSpace.OSpace, out collection))
            {   // if OSpace is not loaded - don't register 
                ObjectItemCollection objItemCollection = (ObjectItemCollection)collection; 
                if (!objItemCollection.LoadAssemblyForType(type) && (null != callingAssembly))
                { 
                    // only load from callingAssembly if all types were filtered
                    // then loaded referenced assemblies of calling assembly

                    // attempt automatic discovery of user types 
                    // interesting code paths are ObjectQuery, ObjectQuery, ObjectQuery
                    // other interesting code paths are ObjectQuery>, ObjectQuery> 
                    // when assemblies is mscorlib, System.Data or System.Data.Entity 
                    objItemCollection.LoadAllReferencedAssemblies(callingAssembly);
                } 
            }
        }

        ///  
        /// If OSpace is not loaded for the specified EntityType
        /// the load metadata from the callingAssembly and its referenced assemblies. 
        ///  
        /// The CSPace type to verify its OSpace counterpart is loaded
        /// The assembly and its referenced assemblies to load when type is insuffiecent 
        internal void LoadFromEntityType(EntityType type, Assembly callingAssembly)
        {
           // used by ObjectContext.*GetObjectByKey when the clr type is not available
           // so we check the OCMap to find the clr type else attempt to autoload the OSpace from callingAssembly 
            Debug.Assert(null != type, "null type");
            Map map; 
            if (!TryGetMap(type, DataSpace.OCSpace, out map)) 
            {   // an OCMap is not exist, attempt to load OSpace to retry
                LoadAssemblyForType(typeof(System.Data.Objects.DataClasses.IEntityWithKey), callingAssembly); 
            }
        }

        ///  
        /// Search for an item with the given identity in the given space.
        /// For example, The identity for EdmType is Namespace.Name. 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in 
        /// if identity argument passed in is null
        /// If the ItemCollection for this space does not have an item with the given identity 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace 
        public T GetItem(string identity, DataSpace dataSpace) where T:GlobalItem
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return collection.GetItem(identity, false /*ignoreCase*/);
        }
 
        /// 
        /// Search for an item with the given identity in the given space. 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        /// if identity or space argument is null 
        public bool TryGetItem(string identity, DataSpace space, out T item ) where T:GlobalItem
        { 
            item = null; 
            ItemCollection collection = GetItemCollection(space, false);
            return (null != collection) && collection.TryGetItem(identity, false /*ignoreCase*/, out item); 
        }

        /// 
        /// Search for an item with the given identity in the given space. 
        /// For example, The identity for EdmType is Namespace.Name.
        ///  
        ///  
        /// 
        ///  
        /// 
        /// 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in 
        /// if identity argument passed in is null
        /// If the ItemCollection for this space does not have an item with the given identity 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace 
        public T GetItem(string identity, bool ignoreCase, DataSpace dataSpace) where T : GlobalItem
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return collection.GetItem(identity, ignoreCase);
        }
 
        /// 
        /// Search for an item with the given identity in the given space. 
        ///  
        /// 
        ///  
        /// 
        /// 
        /// 
        ///  
        /// if identity or space argument is null
        public bool TryGetItem(string identity, bool ignoreCase, DataSpace dataSpace, out T item) where T : GlobalItem 
        { 
            item = null;
            ItemCollection collection = GetItemCollection(dataSpace, false); 
            return (null != collection) && collection.TryGetItem(identity, ignoreCase, out item);
        }

        ///  
        /// Returns ReadOnlyCollection of the Items of the given type
        /// in the workspace. 
        ///  
        /// 
        ///  
        /// 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace 
        public ReadOnlyCollection GetItems(DataSpace dataSpace) where T : GlobalItem
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true); 
            return collection.GetItems();
        } 

        /// 
        /// Search for a type metadata with the specified name and namespace name in the given space.
        ///  
        /// name of the type
        /// namespace of the type 
        /// Dataspace to search the type for 
        /// Returns null if no match found.
        /// if space argument is null 
        /// If ItemCollection has not been registered for the space passed in
        /// if name or namespaceName arguments passed in are null
        /// If the ItemCollection for this space does not have a type with the given name and namespaceName
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace 
        public EdmType GetType(string name, string namespaceName, DataSpace dataSpace)
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true); 
            return collection.GetType(name, namespaceName, false /*ignoreCase*/);
        } 

        /// 
        /// Search for a type metadata with the specified name and namespace name in the given space.
        ///  
        /// name of the type
        /// namespace of the type 
        /// Dataspace to search the type for 
        /// The type that needs to be filled with the return value
        /// Returns false if no match found. 
        /// if name, namespaceName or space argument is null
        public bool TryGetType(string name, string namespaceName, DataSpace dataSpace, out EdmType type)
        {
            type = null; 
            ItemCollection collection = GetItemCollection(dataSpace, false);
            return (null != collection) && collection.TryGetType(name, namespaceName, false /*ignoreCase*/, out type); 
        } 

 

        /// 
        /// Search for a type metadata with the specified name and namespace name in the given space.
        ///  
        /// name of the type
        /// namespace of the type 
        ///  
        /// Dataspace to search the type for
        /// Returns null if no match found. 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in
        /// if name or namespaceName arguments passed in are null
        /// If the ItemCollection for this space does not have a type with the given name and namespaceName 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
        public EdmType GetType(string name, string namespaceName, bool ignoreCase, DataSpace dataSpace) 
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return collection.GetType(name, namespaceName, ignoreCase); 
        }

        /// 
        /// Search for a type metadata with the specified name and namespace name in the given space. 
        /// 
        /// name of the type 
        /// namespace of the type 
        /// Dataspace to search the type for
        ///  
        /// The type that needs to be filled with the return value
        /// Returns null if no match found.
        /// if name, namespaceName or space argument is null
        public bool TryGetType(string name, string namespaceName, bool ignoreCase, 
                               DataSpace dataSpace, out EdmType type)
        { 
            type = null; 
            ItemCollection collection = GetItemCollection(dataSpace, false);
            return (null != collection) && collection.TryGetType(name, namespaceName, ignoreCase, out type); 
        }


        ///  
        /// Get an entity container based upon the strong name of the container
        /// If no entity container is found, returns null, else returns the first one///  
        /// name of the entity container 
        /// 
        /// The EntityContainer 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in
        /// if name argument passed in is null
        /// If the ItemCollection for this space does not have a EntityContainer with the given name 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
        public EntityContainer GetEntityContainer(string name, DataSpace dataSpace) 
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return collection.GetEntityContainer(name); 
        }

        /// 
        /// Get an entity container based upon the strong name of the container 
        /// If no entity container is found, returns null, else returns the first one/// 
        /// name of the entity container 
        ///  
        /// 
        /// if either space or name arguments is null 
        public bool TryGetEntityContainer(string name, DataSpace dataSpace, out EntityContainer entityContainer)
        {
            entityContainer = null;
            // null check exists in call stack, but throws for "identity" not "name" 
            EntityUtil.GenericCheckArgumentNull(name, "name");
            ItemCollection collection = GetItemCollection(dataSpace, false); 
            return (null != collection) && collection.TryGetEntityContainer(name, out entityContainer); 
        }
 
        /// 
        /// Get an entity container based upon the strong name of the container
        /// If no entity container is found, returns null, else returns the first one/// 
        /// name of the entity container 
        /// true for case-insensitive lookup
        ///  
        /// The EntityContainer 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in 
        /// if name argument passed in is null
        /// If the ItemCollection for this space does not have a EntityContainer with the given name
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
        public EntityContainer GetEntityContainer(string name, bool ignoreCase, DataSpace dataSpace) 
        {
            ItemCollection collection = GetItemCollection(dataSpace, true); 
            return collection.GetEntityContainer(name, ignoreCase); 
        }
 
        /// 
        /// Get an entity container based upon the strong name of the container
        /// If no entity container is found, returns null, else returns the first one/// 
        /// name of the entity container 
        /// true for case-insensitive lookup
        ///  
        ///  
        /// if name or space argument is null
        public bool TryGetEntityContainer(string name, bool ignoreCase, 
                                                             DataSpace dataSpace, out EntityContainer entityContainer)
        {
            entityContainer = null;
            // null check exists in call stack, but throws for "identity" not "name" 
            EntityUtil.GenericCheckArgumentNull(name, "name");
            ItemCollection collection = GetItemCollection(dataSpace, false); 
            return (null != collection) && collection.TryGetEntityContainer(name, ignoreCase, out entityContainer); 
        }
 
        /// 
        /// Get all the overloads of the function with the given name
        /// 
        /// name of the function 
        /// namespace of the function
        /// The dataspace for which we need to get the function for 
        /// A collection of all the functions with the given name in the given data space 
        /// if space argument is null
        /// if name or namespaceName argument is null 
        /// If ItemCollection has not been registered for the space passed in
        /// if functionName argument passed in is null
        /// If the ItemCollection for this space does not have a EdmFunction with the given functionName
        /// If the name or namespaceName is empty 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
        public ReadOnlyCollection GetFunctions(string name, string namespaceName, DataSpace dataSpace) 
        { 
            return GetFunctions(name, namespaceName, dataSpace, false /*ignoreCase*/);
        } 

        /// 
        /// Get all the overloads of the function with the given name
        ///  
        /// name of the function
        /// namespace of the function 
        /// The dataspace for which we need to get the function for 
        /// true for case-insensitive lookup
        /// A collection of all the functions with the given name in the given data space 
        /// if space argument is null
        /// if name or namespaceName argument is null
        /// If ItemCollection has not been registered for the space passed in
        /// if functionName argument passed in is null 
        /// If the ItemCollection for this space does not have a EdmFunction with the given functionName
        /// If the name or namespaceName is empty 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace 
        public ReadOnlyCollection GetFunctions(string name,
                                                            string namespaceName, 
                                                            DataSpace dataSpace,
                                                            bool ignoreCase)
        {
            EntityUtil.CheckStringArgument(name, "name"); 
            EntityUtil.CheckStringArgument(namespaceName, "namespaceName");
            ItemCollection collection = GetItemCollection(dataSpace, true); 
 
            // Get the function with this full name, which is namespace name plus name
            return collection.GetFunctions(namespaceName + "." + name, ignoreCase); 
        }

        /// 
        /// Gets the function as specified by the function key 
        /// 
        /// name of the function 
        /// namespace of the function 
        /// types of the parameters
        /// true for case-insensitive lookup 
        /// 
        /// The function that needs to be returned
        ///  The function as specified in the function key or null
        /// if name, namespaceName, parameterTypes or space argument is null 
        internal bool TryGetFunction(string name,
                                   string namespaceName, 
                                   TypeUsage[] parameterTypes, 
                                   bool ignoreCase,
                                   DataSpace dataSpace, 
                                   out EdmFunction function)
        {
            function = null;
            EntityUtil.GenericCheckArgumentNull(name, "name"); 
            EntityUtil.GenericCheckArgumentNull(namespaceName, "namespaceName");
            ItemCollection collection = GetItemCollection(dataSpace, false); 
 
            // Get the function with this full name, which is namespace name plus name
            return (null != collection) && collection.TryGetFunction(namespaceName + "." + name, parameterTypes, ignoreCase, out function); 
        }

        /// 
        /// Get the list of primitive types for the given space 
        /// 
        /// dataspace for which you need the list of primitive types 
        ///  
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in 
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
        public ReadOnlyCollection GetPrimitiveTypes(DataSpace dataSpace)
        {
            ItemCollection collection = GetItemCollection(dataSpace, true); 
            return collection.GetItems();
        } 
 
        /// 
        /// Get all the items in the data space 
        /// 
        /// dataspace for which you need the list of items
        /// 
        /// if space argument is null 
        /// If ItemCollection has not been registered for the space passed in
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace 
        public ReadOnlyCollection GetItems(DataSpace dataSpace) 
        {
            ItemCollection collection = GetItemCollection(dataSpace, true); 
            return collection.GetItems();
        }

        ///  
        /// Given the canonical primitive type, get the mapping primitive type in the given dataspace
        ///  
        /// primitive type kind 
        /// dataspace in which one needs to the mapping primitive types
        /// The mapped scalar type 
        /// if space argument is null
        /// If ItemCollection has not been registered for the space passed in
        /// Thrown if the space is not a valid space. Valid space is either C, O, CS or OCSpace
        internal PrimitiveType GetMappedPrimitiveType(PrimitiveTypeKind primitiveTypeKind, DataSpace dataSpace) 
        {
            ItemCollection collection = GetItemCollection(dataSpace, true); 
            return collection.GetMappedPrimitiveType(primitiveTypeKind); 
        }
 
        /// 
        /// Search for a Mapping metadata with the specified type key.
        /// 
        /// type 
        /// The dataspace that the type for which map needs to be returned belongs to
        /// true for case-insensitive lookup 
        /// space for which you want to get the mapped type 
        /// 
        /// Returns false if no match found. 
        internal bool TryGetMap(string typeIdentity, DataSpace typeSpace, bool ignoreCase, DataSpace mappingSpace, out Map map)
        {
            map = null;
            ItemCollection collection = GetItemCollection(mappingSpace, false); 
            return (null != collection) && ((MappingItemCollection)collection).TryGetMap(typeIdentity, typeSpace, ignoreCase, out map);
        } 
 
        /// 
        /// Search for a Mapping metadata with the specified type key. 
        /// 
        /// typeIdentity of the type
        /// The dataspace that the type for which map needs to be returned belongs to
        /// space for which you want to get the mapped type 
        ///  Thrown if mapping space is not valid
        internal Map GetMap(string identity, DataSpace typeSpace, DataSpace dataSpace) 
        { 
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return ((MappingItemCollection)collection).GetMap(identity, typeSpace); 
        }

        /// 
        /// Search for a Mapping metadata with the specified type key. 
        /// 
        ///  
        /// space for which you want to get the mapped type 
        ///  Thrown if mapping space is not valid
        internal Map GetMap(GlobalItem item, DataSpace dataSpace) 
        {
            ItemCollection collection = GetItemCollection(dataSpace, true);
            return ((MappingItemCollection)collection).GetMap(item);
        } 

        ///  
        /// Search for a Mapping metadata with the specified type key. 
        /// 
        ///  
        /// space for which you want to get the mapped type
        /// 
        /// Returns false if no match found.
        internal bool TryGetMap(GlobalItem item, DataSpace dataSpace, out Map map) 
        {
            map = null; 
            ItemCollection collection = GetItemCollection(dataSpace, false); 
            return (null != collection) && ((MappingItemCollection)collection).TryGetMap(item, out map);
        } 

        private ItemCollection RegisterDefaultObjectMappingItemCollection()
        {
            EdmItemCollection edm = _itemsCSpace as EdmItemCollection; 
            ObjectItemCollection obj = _itemsOSpace as ObjectItemCollection;
            if ((null != edm) && (null != obj)) 
            { 
                RegisterItemCollection(new DefaultObjectMappingItemCollection(edm, obj));
            } 
            return _itemsOCSpace;
        }

        ///  
        /// Get item collection for the space, if registered. If returned, the ItemCollection is in read only mode as it is
        /// part of the workspace. 
        ///  
        /// The dataspace for the item collection that should be returned
        /// The collection registered for the specified dataspace, if any 
        /// true if an item collection is currently registered for the specified space; otherwise false.
        /// if space argument is null
        public bool TryGetItemCollection(DataSpace dataSpace, out ItemCollection collection)
        { 
            collection = GetItemCollection(dataSpace, false);
            return (null != collection); 
        } 

        ///  
        /// Checks if the space is valid and whether the collection is registered for the given space, and if both are valid,
        /// then returns the itemcollection for the given space
        /// 
        ///  
        /// if true, will throw
        /// Thrown if required and mapping space is not valid or registered 
        internal ItemCollection GetItemCollection(DataSpace dataSpace, bool required) 
        {
            ItemCollection collection; 
            switch (dataSpace)
            {
            case DataSpace.CSpace:
                collection = _itemsCSpace; 
                break;
            case DataSpace.OSpace: 
                collection = _itemsOSpace; 
                break;
            case DataSpace.OCSpace: 
                collection = _itemsOCSpace ?? RegisterDefaultObjectMappingItemCollection();
                break;
            case DataSpace.CSSpace:
                collection = _itemsCSSpace; 
                break;
            case DataSpace.SSpace: 
                collection = _itemsSSpace; 
                break;
            default: 
                if (required) {
                    Debug.Fail("Invalid DataSpace Enum value: " + dataSpace);
                }
                collection = null; 
                break;
            } 
            if (required && (null == collection)) { 
                throw EntityUtil.NoCollectionForSpace(dataSpace);
            } 
            return collection;
        }

        ///  
        /// The method returns the OSpace type mapped to the specified Edm Space Type.
        /// If the DataSpace of the argument is not CSpace, or the mapped OSpace type 
        /// cannot be determined, an ArgumentException is thrown. 
        /// 
        /// The CSpace type to look up 
        /// The OSpace type mapped to the supplied argument
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
        public StructuralType GetObjectSpaceType(StructuralType edmSpaceType)
        { 
            StructuralType objectSpaceType;
            if (!this.TryGetObjectSpaceType(edmSpaceType, out objectSpaceType)) 
            { 
                throw EntityUtil.Argument(Strings.FailedToFindOSpaceTypeMapping(edmSpaceType.Identity));
            } 

            return objectSpaceType;
        }
 
        /// 
        /// This method returns the OSpace type mapped to the specified Edm Space Type. 
        /// If the DataSpace of the argument is not CSpace, or if the mapped OSpace type 
        /// cannot be determined, the method returns false and sets the out parameter
        /// to null. 
        /// 
        /// The CSpace type to look up
        /// The OSpace type mapped to the supplied argument
        /// true on success, false on failure 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm")]
        public bool TryGetObjectSpaceType(StructuralType edmSpaceType, out StructuralType objectSpaceType) 
        { 
            EntityUtil.CheckArgumentNull(edmSpaceType, "edmSpaceType");
 
            if (edmSpaceType.DataSpace != DataSpace.CSpace)
            {
                throw EntityUtil.Argument(Strings.ArgumentMustBeCSpaceType, "edmSpaceType");
            } 

            objectSpaceType = null; 
 
            Map map;
            if (!this.TryGetMap(edmSpaceType, DataSpace.OCSpace, out map)) 
            {
                return false;
            }
 
            ObjectTypeMapping ocMap = map as ObjectTypeMapping;
            if (ocMap == null) 
            { 
                return false;
            } 

            objectSpaceType = (StructuralType)ocMap.ClrType;
            return true;
        } 

        ///  
        /// This method returns the Edm Space type mapped to the OSpace Type parameter. If the 
        /// DataSpace of the supplied type is not OSpace, or the mapped Edm Space type cannot
        /// be determined, an ArgumentException is thrown. 
        /// 
        /// The OSpace type to look up
        /// The CSpace type mapped to the OSpace parameter
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")] 
        public StructuralType GetEdmSpaceType(StructuralType objectSpaceType)
        { 
            StructuralType edmSpaceType; 
            if (!this.TryGetEdmSpaceType(objectSpaceType, out edmSpaceType))
            { 
                throw EntityUtil.Argument(Strings.FailedToFindCSpaceTypeMapping(objectSpaceType.Identity));
            }

            return edmSpaceType; 
        }
 
        ///  
        /// This method returns the Edm Space type mapped to the OSpace Type parameter. If the
        /// DataSpace of the supplied type is not OSpace, or the mapped Edm Space type cannot 
        /// be determined, the method returns false and sets the out parameter to null.
        /// 
        /// The OSpace type to look up
        /// The mapped CSpace type 
        /// true on success, false on failure
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "edm"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")] 
        public bool TryGetEdmSpaceType(StructuralType objectSpaceType, out StructuralType edmSpaceType) 
        {
            EntityUtil.CheckArgumentNull(objectSpaceType, "objectSpaceType"); 

            if (objectSpaceType.DataSpace != DataSpace.OSpace)
            {
                throw EntityUtil.Argument(Strings.ArgumentMustBeOSpaceType, "objectSpaceType"); 
            }
 
            edmSpaceType = null; 

            Map map; 
            if (!this.TryGetMap(objectSpaceType, DataSpace.OCSpace, out map))
            {
                return false;
            } 

            ObjectTypeMapping ocMap = map as ObjectTypeMapping; 
            if (ocMap == null) 
            {
                return false; 
            }

            edmSpaceType = (StructuralType)ocMap.EdmType;
            return true; 
        }
 
        /////  
        ///// Returns the update or query view for an Extent as a
        ///// command tree. For a given Extent, MetadataWorkspace will 
        ///// have either a Query view or an Update view but not both.
        ///// 
        ///// 
        /////  
        internal DbQueryCommandTree GetCqtView(EntitySetBase extent)
        { 
            return GetGeneratedView(extent).GetCommandTree(this); 
        }
 
        /// 
        /// Returns generated update or query view for the given extent.
        /// 
        internal GeneratedView GetGeneratedView(EntitySetBase extent) 
        {
            ItemCollection collection = GetItemCollection(DataSpace.CSSpace, true); 
            return ((StorageMappingItemCollection)collection).GetGeneratedView(extent, this); 
        }
 
        /// 
        /// Returns a TypeOf/TypeOfOnly Query for a given Extent and Type as a command tree.
        /// 
        ///  
        /// 
        internal bool TryGetGeneratedViewOfType(EntitySetBase extent, EntityTypeBase type, bool includeSubtypes, out GeneratedView generatedView) 
        { 
            ItemCollection collection = GetItemCollection(DataSpace.CSSpace, true);
            return ((StorageMappingItemCollection)collection).TryGetGeneratedViewOfType(this, extent, type, includeSubtypes, out generatedView); 
        }

        /// 
        /// Determines if a target function exists for the given function import. 
        /// 
        /// Function import (function declared in model entity container) 
        /// Function target mapping (function to which the import is mapped in the target store) 
        /// true if a mapped target function exists; false otherwise
        internal bool TryGetFunctionImportMapping(EdmFunction functionImport, out FunctionImportMapping targetFunctionMapping) 
        {
            ItemCollection collection = GetItemCollection(DataSpace.CSSpace, true);
            return StorageMappingItemCollection.TryGetFunctionImportTarget(functionImport, this, out targetFunctionMapping);
        } 

        ///  
        /// Returns the view loader associated with this workspace, 
        /// creating a loader if non exists. The loader includes
        /// context information used by the update pipeline when 
        /// processing changes to C-space extents.
        /// 
        /// 
        internal ViewLoader GetUpdateViewLoader() 
        {
            if (_itemsCSSpace != null) 
            { 
                return _itemsCSSpace.GetUpdateViewLoader();
            } 
            return null;
        }

 
        /// 
        /// Takes in a Edm space type usage and converts into an 
        /// equivalent O space type usage 
        /// 
        ///  
        /// 
        internal TypeUsage GetOSpaceTypeUsage(TypeUsage edmSpaceTypeUsage)
        {
            EntityUtil.CheckArgumentNull(edmSpaceTypeUsage, "edmSpaceTypeUsage"); 
            if (edmSpaceTypeUsage.EdmType == null)
            { 
                throw EntityUtil.TypeUsageHasNoEdmType("edmSpaceTypeUsage"); 
            }
 
            EdmType clrType = null;
            if (Helper.IsPrimitiveType(edmSpaceTypeUsage.EdmType))
            {
                ItemCollection collection = GetItemCollection(DataSpace.OSpace, true); 
                clrType = collection.GetMappedPrimitiveType(((PrimitiveType)edmSpaceTypeUsage.EdmType).PrimitiveTypeKind);
            } 
            else 
            {
                // Check and throw if the OC space doesn't exist 
                ItemCollection collection = GetItemCollection(DataSpace.OCSpace, true);

                // Get the OC map
                Map map = ((DefaultObjectMappingItemCollection)collection).GetMap(edmSpaceTypeUsage.EdmType); 
                clrType = ((ObjectTypeMapping)map).ClrType;
            } 
 
            Debug.Assert(!Helper.IsPrimitiveType(clrType) ||
                object.ReferenceEquals(ClrProviderManifest.Instance.GetFacetDescriptions(clrType), 
                                                EdmProviderManifest.Instance.GetFacetDescriptions(clrType.BaseType)),
                                                "these are no longer equal so we can't just use the same set of facets for the new type usage");

            // Transfer the facet values 
            TypeUsage result = TypeUsage.Create(clrType, edmSpaceTypeUsage.Facets);
 
            return result; 
        }
 
        /// 
        /// Returns true if the item collection for the given space has already been registered else returns false
        /// 
        ///  
        /// 
        internal bool IsItemCollectionAlreadyRegistered(DataSpace dataSpace) 
        { 
            ItemCollection itemCollection;
            return TryGetItemCollection(dataSpace, out itemCollection); 
        }

        /// 
        /// Requires: C, S and CS are registered in this and other 
        /// Determines whether C, S and CS are equivalent. Useful in determining whether a DbCommandTree
        /// is usable within a particular entity connection. 
        ///  
        /// Other workspace.
        /// true is C, S and CS collections are equivalent 
        internal bool IsMetadataWorkspaceCSCompatible(MetadataWorkspace other)
        {
            Debug.Assert(this.IsItemCollectionAlreadyRegistered(DataSpace.CSSpace) &&
                other.IsItemCollectionAlreadyRegistered(DataSpace.CSSpace), 
                "requires: C, S and CS are registered in this and other");
 
            bool result = this._itemsCSSpace.MetadataEquals(other._itemsCSSpace); 

            Debug.Assert(!result || 
                (this._itemsCSpace.MetadataEquals(other._itemsCSpace) && this._itemsSSpace.MetadataEquals(other._itemsSSpace)),
                "constraint: this.CS == other.CS --> this.S == other.S && this.C == other.C");

            return result; 
        }
 
        ///  
        /// Clear all the metadata cache entries
        ///  
        public static void ClearCache()
        {
            MetadataCache.Clear();
            ObjectItemCollection.ViewGenerationAssemblies.Clear(); 
        }
 
        ///  
        /// Creates a new Metadata workspace sharing the (currently defined) item collections
        /// and tokens for caching purposes. 
        /// 
        /// 
        internal MetadataWorkspace ShallowCopy()
        { 
            MetadataWorkspace copy = (MetadataWorkspace)MemberwiseClone();
            if (null != copy._cacheTokens) { 
                copy._cacheTokens = new List(copy._cacheTokens); 
            }
            return copy; 
        }

        /// 
        /// Returns the canonical Model TypeUsage for a given PrimitiveTypeKind 
        /// 
        /// PrimitiveTypeKind for which a canonical TypeUsage is expected 
        /// a canonical model TypeUsage 
        internal TypeUsage GetCanonicalModelTypeUsage(PrimitiveTypeKind primitiveTypeKind)
        { 
            return EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(primitiveTypeKind);
        }

        ///  
        /// Returns the Model PrimitiveType for a given primitiveTypeKind
        ///  
        /// a PrimitiveTypeKind for which a Model PrimitiveType is expected 
        /// Model PrimitiveType
        internal PrimitiveType GetModelPrimitiveType(PrimitiveTypeKind primitiveTypeKind) 
        {
            return EdmProviderManifest.Instance.GetPrimitiveType(primitiveTypeKind);
        }
 

        // 
        // Returns list of "interesting" members for the given EntitySet/EntityType 
        // Interesting Members are:
        //    0. Key members 
        //    1. Members with C-Side conditions (complex types can not have C-side condition at present)
        //    2. Members participating in association end
        //    3. Members with ConcurrencyMode 'Fixed'
        //      3.1 Complex Members with any child member having Concurrency mode Fixed 
        //    4. Members included in Update ModificationFunction with Version='Original' (Original = Not Current)
        //      4.1 Complex Members in ModificaionFunction if any sub-member is interesting 
        // 
        // Note: Key values are not returned because they are immutable and never "interesting"
        // Abstract EntityTypes are allowed since their parent attributes can be mapped differently. 
        /// 
        /// Returns members of a given EntitySet/EntityType for which original values are necessary for determining which tables to modify.
        /// 
        /// An EntitySet belonging to the C-Space 
        /// An EntityType that participates in the given EntitySet
        /// Edm Members for which original Value is required 
        public IEnumerable GetRequiredOriginalValueMembers(EntitySetBase entitySet, EntityTypeBase entityType) 
        {
            EntityUtil.CheckArgumentNull(entitySet, "entitySet"); 
            EntityUtil.CheckArgumentNull(entityType, "entityType");

            Debug.Assert(entitySet.EntityContainer != null);
 
            //Check that EntitySet is from CSpace
            if (entitySet.EntityContainer.GetDataSpace() != DataSpace.CSpace) 
            { 
                AssociationSet associationSet = entitySet as AssociationSet;
                if (associationSet != null) 
                {
                    throw EntityUtil.AssociationSetNotInCSpace(entitySet.Name);
                }
                else 
                {
                    throw EntityUtil.EntitySetNotInCSpace(entitySet.Name); 
                } 
            }
 
            //Check that entityType belongs to entitySet
            if (!entitySet.ElementType.IsAssignableFrom(entityType))
            {
                AssociationSet associationSet = entitySet as AssociationSet; 
                if (associationSet != null)
                { 
                    throw EntityUtil.TypeNotInAssociationSet(entitySet.Name, entitySet.ElementType.FullName, entityType.FullName); 
                }
                else 
                {
                    throw EntityUtil.TypeNotInEntitySet(entitySet.Name, entitySet.ElementType.FullName, entityType.FullName);
                }
            } 

            StorageMappingItemCollection mappingCollection = (StorageMappingItemCollection)GetItemCollection(DataSpace.CSSpace, true); 
            return mappingCollection.GetRequiredOriginalValueMembers(new Pair(entitySet, entityType)); 
        }
 
        #endregion

        #region Properties
        ///  
        /// Returns the QueryCacheManager hosted by this metadata workspace instance
        ///  
        internal System.Data.Common.QueryCache.QueryCacheManager GetQueryCacheManager() 
        {
            Debug.Assert(null != _itemsSSpace, "_itemsSSpace must not be null"); 
            return _itemsSSpace.QueryCacheManager;
        }
        #endregion
    } 
}

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

                        

                        

Link Menu

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