MetadataWorkspace.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Metadata / MetadataWorkspace.cs / 1305376 / MetadataWorkspace.cs

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

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; 
using System.Globalization; 
using System.Runtime.Versioning;
 

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 assemblies to consider 
        /// 
        /// Throw when assembliesToConsider is empty or contains null, or cannot find the corresponding assembly in it 
        ///  
        [ResourceExposure(ResourceScope.Machine)] //Exposes the file path names which are a Machine resource
        [ResourceConsumption(ResourceScope.Machine)] //For MetadataWorkspace.CreateMetadataWorkspaceWithResolver method call but we do not create the file paths in this method 
        public MetadataWorkspace(IEnumerable paths, IEnumerable assembliesToConsider)
        {
            // we are intentionally not checking to see if the paths enumerable is empty
            EntityUtil.CheckArgumentNull(paths, "paths"); 
            EntityUtil.CheckArgumentContainsNull(ref paths, "paths");
 
            EntityUtil.CheckArgumentNull(assembliesToConsider, "assembliesToConsider"); 
            EntityUtil.CheckArgumentContainsNull(ref assembliesToConsider, "assembliesToConsider");
 
            Func resolveReference = (AssemblyName referenceName)=>
            {
                foreach(Assembly assembly in assembliesToConsider)
                { 
                    if (AssemblyName.ReferenceMatchesDefinition(referenceName, new AssemblyName(assembly.FullName)))
                    { 
                        return assembly; 
                    }
                } 
                throw EntityUtil.Argument(Strings.AssemblyMissingFromAssembliesToConsider(referenceName.FullName), "assembliesToConsider");
            };

 
            CreateMetadataWorkspaceWithResolver(paths, () => assembliesToConsider, resolveReference);
        } 
 
        [ResourceExposure(ResourceScope.Machine)] //Exposes the file path names which are a Machine resource
        [ResourceConsumption(ResourceScope.Machine)] //For MetadataArtifactLoader.CreateCompositeFromFilePaths method call but We do not create the file paths in this method 
        private void CreateMetadataWorkspaceWithResolver(IEnumerable paths, Func> wildcardAssemblies, Func 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; 
        private bool _foundAssemblyWithAttribute = false; 
        private double _schemaVersion = XmlConstants.UndefinedVersion;
        private Guid _metadataWorkspaceId = Guid.Empty; 
        #endregion

        #region public static Fields
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")] 
        private static IEnumerable SupportedEdmVersions
        { 
            get 
            {
                yield return XmlConstants.UndefinedVersion; 
                yield return XmlConstants.EdmVersionForV1;
                Debug.Assert(XmlConstants.SchemaVersionLatest == XmlConstants.EdmVersionForV2, "Did you add a new version?");
                yield return XmlConstants.EdmVersionForV2;
            } 
        }
        //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 = SupportedEdmVersions.Last();
        #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
        [CLSCompliant(false)]
        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
        [CLSCompliant(false)] 
        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 (!MetadataWorkspace.SupportedEdmVersions.Contains(edmCollection.EdmVersion))
                        { 
 
                            throw EntityUtil.InvalidOperation(
                                System.Data.Entity.Strings.EdmVersionNotSupportedByRuntime( 
                                edmCollection.EdmVersion,
                                Helper.GetCommaDelimitedString(
                                    SupportedEdmVersions
                                        .Where(e => e != XmlConstants.UndefinedVersion) 
                                        .Select(e => e.ToString(CultureInfo.InvariantCulture)))));
                        } 
 
                        CheckAndSetItemCollectionVersionInWorkSpace(collection);
 
                        _itemsCSpace = edmCollection;
                    }
                    break;
                case DataSpace.SSpace: 
                    if (null == (existing = _itemsSSpace))
                    { 
                        CheckAndSetItemCollectionVersionInWorkSpace(collection); 
                        _itemsSSpace = (StoreItemCollection)collection;
                    } 
                    break;
                case DataSpace.OSpace:
                    if (null == (existing = _itemsOSpace)) {
                        _itemsOSpace = (ObjectItemCollection)collection; 
                    }
                    break; 
                case DataSpace.CSSpace: 
                    if (null == (existing = _itemsCSSpace)) {
                        CheckAndSetItemCollectionVersionInWorkSpace(collection); 
                        _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);
                } 
            }
        } 
 
        /// 
        /// 
        /// 
        /// 
        private void CheckAndSetItemCollectionVersionInWorkSpace(ItemCollection itemCollectionToRegister)
        { 
            double versionToRegister = XmlConstants.UndefinedVersion;
            string itemCollectionType = null; 
            switch (itemCollectionToRegister.DataSpace) 
            {
                case DataSpace.CSpace: 
                    versionToRegister = ((EdmItemCollection)itemCollectionToRegister).EdmVersion;
                    itemCollectionType = "EdmItemCollection";
                    break;
                case DataSpace.SSpace: 
                    versionToRegister = ((StoreItemCollection)itemCollectionToRegister).SchemaVersion;
                    itemCollectionType = "StoreItemCollection"; 
                    break; 
                case DataSpace.CSSpace:
                    versionToRegister = ((StorageMappingItemCollection)itemCollectionToRegister).MappingVersion; 
                    itemCollectionType = "StorageMappingItemCollection";
                    break;
                default:
                    // we don't care about other spaces so keep the _versionToRegister to Undefined 
                    break;
            } 
 
            if (versionToRegister != this._schemaVersion &&
                versionToRegister != XmlConstants.UndefinedVersion && 
                this._schemaVersion != XmlConstants.UndefinedVersion)
            {
                Debug.Assert(itemCollectionType != null);
                throw EntityUtil.DifferentSchemaVersionInCollection(itemCollectionType, versionToRegister, this._schemaVersion); 
            }
            else 
            { 
                this._schemaVersion = versionToRegister;
            } 
        }
        /// 
        /// 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) 
        {
            LoadFromAssembly(assembly, null); 
        } 

        ///  
        /// Load metadata from the given assembly
        /// 
        /// The assembly from which to load metadata
        /// The delegate for logging the load messages 
        /// thrown if assembly argument is null
        public void LoadFromAssembly(Assembly assembly, Action logLoadMessage) 
        { 
            EntityUtil.CheckArgumentNull(assembly, "assembly");
            ObjectItemCollection collection = (ObjectItemCollection)GetItemCollection(DataSpace.OSpace); 
            ExplicitLoadFromAssembly(assembly, collection, logLoadMessage);
        }

        private void ExplicitLoadFromAssembly(Assembly assembly, ObjectItemCollection collection, Action logLoadMessage) 
        {
            ItemCollection itemCollection; 
            if (!TryGetItemCollection(DataSpace.CSpace, out itemCollection)) 
            {
                itemCollection = null; 
            }

            collection.ExplicitLoadFromAssembly(assembly, (EdmItemCollection)itemCollection, logLoadMessage);
        } 

        private void ImplicitLoadFromAssembly(Assembly assembly, ObjectItemCollection collection) 
        { 
            if (!MetadataAssemblyHelper.ShouldFilterAssembly(assembly))
            { 
                ExplicitLoadFromAssembly(assembly, collection, null);
            }
        }
 
        /// 
        /// Implicit loading means that we are trying to help the user find the right 
        /// assembly, but they didn't explicitly ask for it. Our Implicit rules require that 
        /// we filter out assemblies with the Ecma or MicrosoftPublic PublicKeyToken on them
        /// 
        /// 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 ImplicitLoadAssemblyForType(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;
                ItemCollection edmItemCollection; 
                TryGetItemCollection(DataSpace.CSpace, out edmItemCollection); 
                if (!objItemCollection.ImplicitLoadAssemblyForType(type, (EdmItemCollection)edmItemCollection) && (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 

 		            // If the schema attribute is presented on the assembly or any referenced assemblies, then it is a V1 scenario that we should 
                    // strictly follow the Get all referenced assemblies rules.
                    // If the attribute is not presented on the assembly, then we won't load the referenced ----sembly
                    // for this callingAssembly
                    if (ObjectItemAttributeAssemblyLoader.IsSchemaAttributePresent(callingAssembly) || 
                        (_foundAssemblyWithAttribute ||
                          MetadataAssemblyHelper.GetNonSystemReferencedAssemblies(callingAssembly).Any(a => ObjectItemAttributeAssemblyLoader.IsSchemaAttributePresent(a)))) 
                    { 
                        // cache the knowledge that we found an attribute
                        // because it can be expesive to figure out 
                        _foundAssemblyWithAttribute = true;
                        objItemCollection.ImplicitLoadAllReferencedAssemblies(callingAssembly, (EdmItemCollection)edmItemCollection);
                    }
                    else 
                    {
                        this.ImplicitLoadFromAssembly(callingAssembly, objItemCollection); 
                    } 
                }
            } 
        }

        /// 
        /// 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 ImplicitLoadFromEntityType(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 
                ImplicitLoadAssemblyForType(typeof(System.Data.Objects.DataClasses.IEntityWithKey), callingAssembly);
 
                // We do a check here to see if the type was actually found in the attempted load.
                ObjectItemCollection ospaceCollection = GetItemCollection(DataSpace.OSpace) as ObjectItemCollection;
                EdmType ospaceType;
                if (ospaceCollection == null || !ospaceCollection.TryGetOSpaceType(type, out ospaceType)) 
                {
                    throw new InvalidOperationException(System.Data.Entity.Strings.Mapping_Object_InvalidType(type.Identity)); 
                } 
            }
        } 

        /// 
        /// 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.
        /// All parameters are assumed to be .
        ///  
        /// 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
        [CLSCompliant(false)]
        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);
        }

        ///  
        /// Returns generated function definition for the given function.
        /// Guarantees type match of declaration and generated parameters. 
        /// Guarantees return type match. 
        /// Throws internal error for functions without definition.
        /// Passes thru exception occured during definition generation. 
        /// 
        internal DbLambda GetGeneratedFunctionDefinition(EdmFunction function)
        {
            ItemCollection collection = GetItemCollection(DataSpace.CSpace, true); 
            return ((EdmItemCollection)collection).GetGeneratedFunctionDefinition(function);
        } 
 
        /// 
        /// 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"); 
            Debug.Assert(edmSpaceTypeUsage.EdmType != null, "The TypeUsage object does not have an EDMType.");

            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(); 
            using (LockedAssemblyCache cache = AssemblyCache.AquireLockedAssemblyCache()) 
            {
                cache.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.DataSpace != 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; 
        }
 
        internal double SchemaVersion
        {
            get { return this._schemaVersion; }
            private set { this._schemaVersion = value; } 
        }
 
        internal Guid MetadataWorkspaceId 
        {
            get 
            {
                if (Guid.Equals(Guid.Empty, _metadataWorkspaceId))
                {
                    _metadataWorkspaceId = Guid.NewGuid(); 
                }
                return _metadataWorkspaceId; 
            } 
        }
        #endregion 
    }
}

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

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; 
using System.Globalization; 
using System.Runtime.Versioning;
 

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 assemblies to consider 
        /// 
        /// Throw when assembliesToConsider is empty or contains null, or cannot find the corresponding assembly in it 
        ///  
        [ResourceExposure(ResourceScope.Machine)] //Exposes the file path names which are a Machine resource
        [ResourceConsumption(ResourceScope.Machine)] //For MetadataWorkspace.CreateMetadataWorkspaceWithResolver method call but we do not create the file paths in this method 
        public MetadataWorkspace(IEnumerable paths, IEnumerable assembliesToConsider)
        {
            // we are intentionally not checking to see if the paths enumerable is empty
            EntityUtil.CheckArgumentNull(paths, "paths"); 
            EntityUtil.CheckArgumentContainsNull(ref paths, "paths");
 
            EntityUtil.CheckArgumentNull(assembliesToConsider, "assembliesToConsider"); 
            EntityUtil.CheckArgumentContainsNull(ref assembliesToConsider, "assembliesToConsider");
 
            Func resolveReference = (AssemblyName referenceName)=>
            {
                foreach(Assembly assembly in assembliesToConsider)
                { 
                    if (AssemblyName.ReferenceMatchesDefinition(referenceName, new AssemblyName(assembly.FullName)))
                    { 
                        return assembly; 
                    }
                } 
                throw EntityUtil.Argument(Strings.AssemblyMissingFromAssembliesToConsider(referenceName.FullName), "assembliesToConsider");
            };

 
            CreateMetadataWorkspaceWithResolver(paths, () => assembliesToConsider, resolveReference);
        } 
 
        [ResourceExposure(ResourceScope.Machine)] //Exposes the file path names which are a Machine resource
        [ResourceConsumption(ResourceScope.Machine)] //For MetadataArtifactLoader.CreateCompositeFromFilePaths method call but We do not create the file paths in this method 
        private void CreateMetadataWorkspaceWithResolver(IEnumerable paths, Func> wildcardAssemblies, Func 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; 
        private bool _foundAssemblyWithAttribute = false; 
        private double _schemaVersion = XmlConstants.UndefinedVersion;
        private Guid _metadataWorkspaceId = Guid.Empty; 
        #endregion

        #region public static Fields
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Edm")] 
        private static IEnumerable SupportedEdmVersions
        { 
            get 
            {
                yield return XmlConstants.UndefinedVersion; 
                yield return XmlConstants.EdmVersionForV1;
                Debug.Assert(XmlConstants.SchemaVersionLatest == XmlConstants.EdmVersionForV2, "Did you add a new version?");
                yield return XmlConstants.EdmVersionForV2;
            } 
        }
        //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 = SupportedEdmVersions.Last();
        #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
        [CLSCompliant(false)]
        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
        [CLSCompliant(false)] 
        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 (!MetadataWorkspace.SupportedEdmVersions.Contains(edmCollection.EdmVersion))
                        { 
 
                            throw EntityUtil.InvalidOperation(
                                System.Data.Entity.Strings.EdmVersionNotSupportedByRuntime( 
                                edmCollection.EdmVersion,
                                Helper.GetCommaDelimitedString(
                                    SupportedEdmVersions
                                        .Where(e => e != XmlConstants.UndefinedVersion) 
                                        .Select(e => e.ToString(CultureInfo.InvariantCulture)))));
                        } 
 
                        CheckAndSetItemCollectionVersionInWorkSpace(collection);
 
                        _itemsCSpace = edmCollection;
                    }
                    break;
                case DataSpace.SSpace: 
                    if (null == (existing = _itemsSSpace))
                    { 
                        CheckAndSetItemCollectionVersionInWorkSpace(collection); 
                        _itemsSSpace = (StoreItemCollection)collection;
                    } 
                    break;
                case DataSpace.OSpace:
                    if (null == (existing = _itemsOSpace)) {
                        _itemsOSpace = (ObjectItemCollection)collection; 
                    }
                    break; 
                case DataSpace.CSSpace: 
                    if (null == (existing = _itemsCSSpace)) {
                        CheckAndSetItemCollectionVersionInWorkSpace(collection); 
                        _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);
                } 
            }
        } 
 
        /// 
        /// 
        /// 
        /// 
        private void CheckAndSetItemCollectionVersionInWorkSpace(ItemCollection itemCollectionToRegister)
        { 
            double versionToRegister = XmlConstants.UndefinedVersion;
            string itemCollectionType = null; 
            switch (itemCollectionToRegister.DataSpace) 
            {
                case DataSpace.CSpace: 
                    versionToRegister = ((EdmItemCollection)itemCollectionToRegister).EdmVersion;
                    itemCollectionType = "EdmItemCollection";
                    break;
                case DataSpace.SSpace: 
                    versionToRegister = ((StoreItemCollection)itemCollectionToRegister).SchemaVersion;
                    itemCollectionType = "StoreItemCollection"; 
                    break; 
                case DataSpace.CSSpace:
                    versionToRegister = ((StorageMappingItemCollection)itemCollectionToRegister).MappingVersion; 
                    itemCollectionType = "StorageMappingItemCollection";
                    break;
                default:
                    // we don't care about other spaces so keep the _versionToRegister to Undefined 
                    break;
            } 
 
            if (versionToRegister != this._schemaVersion &&
                versionToRegister != XmlConstants.UndefinedVersion && 
                this._schemaVersion != XmlConstants.UndefinedVersion)
            {
                Debug.Assert(itemCollectionType != null);
                throw EntityUtil.DifferentSchemaVersionInCollection(itemCollectionType, versionToRegister, this._schemaVersion); 
            }
            else 
            { 
                this._schemaVersion = versionToRegister;
            } 
        }
        /// 
        /// 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) 
        {
            LoadFromAssembly(assembly, null); 
        } 

        ///  
        /// Load metadata from the given assembly
        /// 
        /// The assembly from which to load metadata
        /// The delegate for logging the load messages 
        /// thrown if assembly argument is null
        public void LoadFromAssembly(Assembly assembly, Action logLoadMessage) 
        { 
            EntityUtil.CheckArgumentNull(assembly, "assembly");
            ObjectItemCollection collection = (ObjectItemCollection)GetItemCollection(DataSpace.OSpace); 
            ExplicitLoadFromAssembly(assembly, collection, logLoadMessage);
        }

        private void ExplicitLoadFromAssembly(Assembly assembly, ObjectItemCollection collection, Action logLoadMessage) 
        {
            ItemCollection itemCollection; 
            if (!TryGetItemCollection(DataSpace.CSpace, out itemCollection)) 
            {
                itemCollection = null; 
            }

            collection.ExplicitLoadFromAssembly(assembly, (EdmItemCollection)itemCollection, logLoadMessage);
        } 

        private void ImplicitLoadFromAssembly(Assembly assembly, ObjectItemCollection collection) 
        { 
            if (!MetadataAssemblyHelper.ShouldFilterAssembly(assembly))
            { 
                ExplicitLoadFromAssembly(assembly, collection, null);
            }
        }
 
        /// 
        /// Implicit loading means that we are trying to help the user find the right 
        /// assembly, but they didn't explicitly ask for it. Our Implicit rules require that 
        /// we filter out assemblies with the Ecma or MicrosoftPublic PublicKeyToken on them
        /// 
        /// 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 ImplicitLoadAssemblyForType(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;
                ItemCollection edmItemCollection; 
                TryGetItemCollection(DataSpace.CSpace, out edmItemCollection); 
                if (!objItemCollection.ImplicitLoadAssemblyForType(type, (EdmItemCollection)edmItemCollection) && (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 

 		            // If the schema attribute is presented on the assembly or any referenced assemblies, then it is a V1 scenario that we should 
                    // strictly follow the Get all referenced assemblies rules.
                    // If the attribute is not presented on the assembly, then we won't load the referenced ----sembly
                    // for this callingAssembly
                    if (ObjectItemAttributeAssemblyLoader.IsSchemaAttributePresent(callingAssembly) || 
                        (_foundAssemblyWithAttribute ||
                          MetadataAssemblyHelper.GetNonSystemReferencedAssemblies(callingAssembly).Any(a => ObjectItemAttributeAssemblyLoader.IsSchemaAttributePresent(a)))) 
                    { 
                        // cache the knowledge that we found an attribute
                        // because it can be expesive to figure out 
                        _foundAssemblyWithAttribute = true;
                        objItemCollection.ImplicitLoadAllReferencedAssemblies(callingAssembly, (EdmItemCollection)edmItemCollection);
                    }
                    else 
                    {
                        this.ImplicitLoadFromAssembly(callingAssembly, objItemCollection); 
                    } 
                }
            } 
        }

        /// 
        /// 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 ImplicitLoadFromEntityType(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 
                ImplicitLoadAssemblyForType(typeof(System.Data.Objects.DataClasses.IEntityWithKey), callingAssembly);
 
                // We do a check here to see if the type was actually found in the attempted load.
                ObjectItemCollection ospaceCollection = GetItemCollection(DataSpace.OSpace) as ObjectItemCollection;
                EdmType ospaceType;
                if (ospaceCollection == null || !ospaceCollection.TryGetOSpaceType(type, out ospaceType)) 
                {
                    throw new InvalidOperationException(System.Data.Entity.Strings.Mapping_Object_InvalidType(type.Identity)); 
                } 
            }
        } 

        /// 
        /// 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.
        /// All parameters are assumed to be .
        ///  
        /// 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
        [CLSCompliant(false)]
        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);
        }

        ///  
        /// Returns generated function definition for the given function.
        /// Guarantees type match of declaration and generated parameters. 
        /// Guarantees return type match. 
        /// Throws internal error for functions without definition.
        /// Passes thru exception occured during definition generation. 
        /// 
        internal DbLambda GetGeneratedFunctionDefinition(EdmFunction function)
        {
            ItemCollection collection = GetItemCollection(DataSpace.CSpace, true); 
            return ((EdmItemCollection)collection).GetGeneratedFunctionDefinition(function);
        } 
 
        /// 
        /// 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"); 
            Debug.Assert(edmSpaceTypeUsage.EdmType != null, "The TypeUsage object does not have an EDMType.");

            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(); 
            using (LockedAssemblyCache cache = AssemblyCache.AquireLockedAssemblyCache()) 
            {
                cache.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.DataSpace != 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; 
        }
 
        internal double SchemaVersion
        {
            get { return this._schemaVersion; }
            private set { this._schemaVersion = value; } 
        }
 
        internal Guid MetadataWorkspaceId 
        {
            get 
            {
                if (Guid.Equals(Guid.Empty, _metadataWorkspaceId))
                {
                    _metadataWorkspaceId = Guid.NewGuid(); 
                }
                return _metadataWorkspaceId; 
            } 
        }
        #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