Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Metadata / ObjectItemCollection.cs / 4 / ObjectItemCollection.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Xml.Serialization; using System.Xml; using System.Xml.Schema; using System.Data.Common.Utils; using System.Diagnostics; using System.Collections.ObjectModel; // Using an alias for this because a lot of names in this namespace conflicts with names in metadata using DataClasses = System.Data.Objects.DataClasses; using System.Globalization; using System.Data.Entity; using System.Data.Common; namespace System.Data.Metadata.Edm { ////// Class for representing a collection of items for the object layer. /// Most of the implemetation for actual maintainance of the collection is /// done by ItemCollection /// public sealed partial class ObjectItemCollection : ItemCollection { #region Constructors ////// The ObjectItemCollection that loads metadata from assemblies /// public ObjectItemCollection() : base(DataSpace.OSpace) { foreach (PrimitiveType type in ClrProviderManifest.Instance.GetStoreTypes()) { AddInternal(type); _primitiveTypeMaps.Add(type); } } #endregion #region Fields // Cache for primitive type maps for Edm to provider private readonly CacheForPrimitiveTypes _primitiveTypeMaps = new CacheForPrimitiveTypes(); // Used for tracking the loading of an assembly and its referenced assemblies. Though the value of an entry is bool, the logic represented // by an entry is tri-state, the third state represented by a "missing" entry. To summarize: // 1. Theassociated with an is "true" : Specified and all referenced assemblies have been loaded // 2. The associated with an is "false" : Specified assembly loaded. Its referenced assemblies may not be loaded // 3. The is missing : Specified assembly has not been loaded private Dictionary _knownAssemblies = new Dictionary (); // Dictionary which keeps tracks of oc mapping information - the key is the conceptual name of the type // and the value is the reference to the ospace type private Dictionary _ocMapping = new Dictionary (); private const string EcmPublicKeyToken = "PublicKeyToken=" + AssemblyRef.EcmaPublicKey; private object _loadAssemblyLock = new object(); internal object LoadAssemblyLock { get { return _loadAssemblyLock; } } internal static IList ViewGenerationAssemblies { get { return AssemblyCacheEntry.ViewGenerationAssemblies; } } #endregion #region Methods /// Is the assembly and its referened assemblies not expected to have any metadata internal static bool ShouldFilterAssembly(string fullName) { return (fullName.EndsWith(EcmPublicKeyToken, StringComparison.OrdinalIgnoreCase)); } internal static bool IsSchemaAttributePresent(Assembly assembly) { return assembly.IsDefined(typeof(DataClasses.EdmSchemaAttribute), false /*inherit*/); } internal static bool IsCompiledViewGenAttributePresent(Assembly assembly) { return assembly.IsDefined(typeof(System.Data.Mapping.EntityViewGenerationAttribute), false /*inherit*/); } ////// The method loads the O-space metadata for all the referenced assemblies starting from the given assembly /// in a recursive way. /// The assembly should be from Assembly.GetCallingAssembly via one of our public API's. /// /// assembly whose dependency list we are going to traverse internal void LoadAllReferencedAssemblies(Assembly assembly) { this.LoadAllReferencedAssemblies(assembly, false); } ////// The method loads all the referenced assemblies starting from the given assembly in a recursive way. /// The assembly should be from Assembly.GetCallingAssembly via one of our public API's. /// /// assembly whose dependency list we are going to traverse /// internal void LoadAllReferencedAssemblies(Assembly assembly, bool loadOnlyViewGenInfo) { if (loadOnlyViewGenInfo) { if (!ShouldFilterAssembly(assembly.FullName)) { lock (this) { CollectIfViewGenAssembly(assembly); foreach (AssemblyName asmName in assembly.GetReferencedAssemblies()) { string fullName = asmName.FullName; if (!ShouldFilterAssembly(fullName)) { // filter out "known" assemblies to prevent unnecessary loading Bid.Trace("loadededAssembly='%ls'\n", fullName); Assembly loadedAssembly = AssemblyCacheEntry.SafeLoadReferencedAssembly(fullName); if (loadedAssembly == null) { continue; } CollectIfViewGenAssembly(loadedAssembly); } } } } } else { LoadAssemblyFromCache(this, assembly, true /*loadAllReferencedAssemblies*/); } } /// /// Load metadata from the given assembly /// /// The assembly from which to load metadata ///thrown if assembly argument is null public void LoadFromAssembly(Assembly assembly) { EntityUtil.CheckArgumentNull(assembly, "assembly"); EntityBid.Trace("assembly='%ls'\n", assembly.FullName); LoadAssemblyFromCache(this, assembly, false /*loadAllReferencedAssemblies*/); //Since User called LoadFromAssembly, so we should collect the generated views if present //even if the schema attribute is not present if (IsCompiledViewGenAttributePresent(assembly) && !IsSchemaAttributePresent(assembly) ) { CollectIfViewGenAssembly(assembly); } } /// /// Load metadata from the type's assembly. /// /// The type's assembly is loaded into the OSpace ItemCollection ///true if the type and all its generic arguments are filtered out (did not attempt to load assembly) internal bool LoadAssemblyForType(Type type) { bool result; // InternalLoadFromAssembly will check _knownAssemblies result = LoadAssemblyFromCache(this, type.Assembly, false /*loadAllReferencedAssemblies*/); if (type.IsGenericType) { // recursively load all generic types // interesting code paths are ObjectQuery>, ObjectQuery > foreach (Type t in type.GetGenericArguments()) { result |= LoadAssemblyForType(t); } } return result; } /// /// internal static method to get the relationship name /// /// /// ///internal AssociationType GetRelationshipType(Type entityClrType, string relationshipName, out string fullSearchName) { fullSearchName = relationshipName; AssociationType associationType; if (TryGetItem (relationshipName, out associationType)) { return associationType; } else if (!IsQualifiedName(relationshipName)) { // they send us unqualified relationship names, try to make it fully qualified EntityType entityType; if (TryGetItem (entityClrType.FullName, out entityType)) { // get the c-space namespace string namespaceName = System.Data.EntityModel.SchemaObjectModel.Utils.GetEverythingBeforeLastPeriod(((ClrEntityType)entityType).CSpaceTypeName); fullSearchName = namespaceName + "." + relationshipName; if(TryGetItem (fullSearchName, out associationType)) { return associationType; } } } return null; } /// /// Loads the OSpace types in the assembly and returns them as a dictionary /// /// The assembly to load ///A mapping from names to OSpace EdmTypes private static DictionaryLoadTypesExpensiveWay(Assembly assembly) { Dictionary typesInLoading = null; // If the assembly is not one of the filtered assemblies and has the schema attribute if (!ShouldFilterAssembly(assembly.FullName) && IsSchemaAttributePresent(assembly)) { List errors; Dictionary knownAssemblies = new Dictionary (); AssemblyCacheEntry.LoadAssemblyFromCache(assembly, false /*loadAllReferencedAssemblies*/, knownAssemblies, out typesInLoading, out errors); // Check for errors if (errors.Count != 0) { throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(errors)); } } return typesInLoading; } /// /// internal static method to get the relationship name /// /// /// ///internal static AssociationType GetRelationshipTypeExpensiveWay(Type entityClrType, string relationshipName, out string fullSearchName) { fullSearchName = relationshipName; Dictionary typesInLoading = LoadTypesExpensiveWay(entityClrType.Assembly); if (typesInLoading != null) { EdmType edmType; // Look in typesInLoading for relationship type if (typesInLoading.TryGetValue(relationshipName, out edmType) && Helper.IsRelationshipType(edmType)) { return (AssociationType)edmType; } else if (!IsQualifiedName(relationshipName)) { string namespaceName = GetModelNamespaceForEntityType(typesInLoading, entityClrType); fullSearchName = namespaceName + "." + relationshipName; if (namespaceName != null && typesInLoading.TryGetValue(fullSearchName, out edmType) && Helper.IsRelationshipType(edmType)) { return (AssociationType)edmType; } } } return null; } /// /// internal static method to get all the AssociationTypes from an assembly /// /// The assembly from which to load relationship types ///An enumeration of OSpace AssociationTypes that are present in this assembly internal static IEnumerableGetAllRelationshipTypesExpensiveWay(Assembly assembly) { Dictionary typesInLoading = LoadTypesExpensiveWay(assembly); if (typesInLoading != null) { // Iterate through the EdmTypes looking for AssociationTypes foreach (EdmType edmType in typesInLoading.Values) { if (Helper.IsAssociationType(edmType)) { yield return (AssociationType)edmType; } } } yield break; } private static string GetModelNamespaceForEntityType(Dictionary typesInLoading,Type entityClrType) { EdmType edmType; if(typesInLoading.TryGetValue(entityClrType.FullName, out edmType) && Helper.IsEntityType(edmType)) { return System.Data.EntityModel.SchemaObjectModel.Utils.GetEverythingBeforeLastPeriod(((ClrEntityType)edmType).CSpaceTypeName); } return null; } private static bool IsQualifiedName(string relationshipName) { return relationshipName.Contains("."); } private static bool LoadAssemblyFromCache(ObjectItemCollection objectItemCollection, Assembly assembly, bool loadReferencedAssemblies) { if (ShouldFilterAssembly(assembly.FullName)) { return false; } // Check if its loaded in the cache - if the call is for loading referenced assemblies, make sure that all referenced // assemblies are also loaded bool areReferencedAssembliesLoaded; if (objectItemCollection._knownAssemblies.TryGetValue(assembly, out areReferencedAssembliesLoaded)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false || areReferencedAssembliesLoaded == true) { return true; } } // Check for schema attribute - if we need to load all the referenced assemblies, then we should continue // even if the root assembly doesn't have the attribute present if (!IsSchemaAttributePresent(assembly) && !loadReferencedAssemblies) { return false; } lock (objectItemCollection.LoadAssemblyLock) { // Check after acquiring the lock, since the known assemblies might have got modified // Check if the assembly is already loaded. The reason we need to check if the assembly is already loaded, is that if (objectItemCollection._knownAssemblies.TryGetValue(assembly, out areReferencedAssembliesLoaded)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false || areReferencedAssembliesLoaded == true) { return true; } } Dictionary typesInLoading; List errors; Dictionary knownAssemblies; if (objectItemCollection != null) { knownAssemblies = new Dictionary (objectItemCollection._knownAssemblies); } else { knownAssemblies = new Dictionary (); } // Load the assembly from the cache AssemblyCacheEntry.LoadAssemblyFromCache(assembly, loadReferencedAssemblies, knownAssemblies, out typesInLoading, out errors); // Throw if we have encountered errors if (errors.Count != 0) { throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(errors)); } // We can encounter new assemblies, but they may not have any time in them if (typesInLoading.Count != 0) { Debug.Assert(knownAssemblies.Count != objectItemCollection._knownAssemblies.Count, "Since there are no types loaded, some assemblies must have got loaded"); // No errors, so go ahead and add the types and make them readonly // The existence of the loading lock tells us whether we should be thread safe or not, if we need // to be thread safe, then we need to use AtomicAddRange. We don't need to actually use the lock // because the caller should have done it already // Recheck the assemblies added, another list is created just to match up the collection type // taken in by AtomicAddRange() List globalItems = new List (); foreach (EdmType edmType in typesInLoading.Values) { globalItems.Add(edmType); try { // Also populate the ocmapping information if (BuiltInTypeKind.EntityType == edmType.BuiltInTypeKind) { objectItemCollection._ocMapping.Add(((ClrEntityType)edmType).CSpaceTypeName, edmType); } else if (BuiltInTypeKind.ComplexType == edmType.BuiltInTypeKind) { objectItemCollection._ocMapping.Add(((ClrComplexType)edmType).CSpaceTypeName, edmType); } // for rest of the types like relationship type, we do not have oc mapping, so we don't keep // to keep that information } catch (ArgumentException e) { throw new MappingException(Strings.Mapping_CannotMapCLRTypeMultipleTimes(edmType.Identity), e); } } // Create a new ObjectItemCollection and add all the global items to it. // Also copy all the existing items from the existing collection objectItemCollection.AtomicAddRange(globalItems); // Update the value of known assemblies objectItemCollection._knownAssemblies = knownAssemblies; foreach (Assembly loadedAssembly in knownAssemblies.Keys) { CollectIfViewGenAssembly(loadedAssembly); } } } return true; } /// /// Check to see if the assembly has the custom view generation attribute AND /// collect the assembly into the local list if it has cutom attribute. /// /// /// private static void CollectIfViewGenAssembly(Assembly assembly) { if (assembly.IsDefined(typeof(System.Data.Mapping.EntityViewGenerationAttribute), false /*inherit*/)) { if (!AssemblyCacheEntry.ViewGenerationAssemblies.Contains(assembly)) { AssemblyCacheEntry.ViewGenerationAssemblies.Add(assembly); } } } ////// Get the list of primitive types for the given space /// ///public IEnumerable GetPrimitiveTypes() { return _primitiveTypeMaps.GetTypes(); } /// /// The method returns the underlying CLR type for the specified OSpace type argument. /// If the DataSpace of the parameter is not OSpace, an ArgumentException is thrown. /// /// The OSpace type to look up ///The CLR type of the OSpace argument public Type GetClrType(StructuralType objectSpaceType) { Type clrType; if (!this.TryGetClrType(objectSpaceType, out clrType)) { throw EntityUtil.Argument(Strings.FailedToFindClrTypeMapping(objectSpaceType.Identity)); } return clrType; } ////// The method returns the underlying CLR type for the specified OSpace type argument. /// If the DataSpace of the parameter is not OSpace, the method returns false and sets /// the out parameter to null. /// /// The OSpace type to look up /// The CLR type of the OSpace argument ///true on success, false on failure public bool TryGetClrType(StructuralType objectSpaceType, out Type clrType) { EntityUtil.CheckArgumentNull(objectSpaceType, "objectSpaceType"); if (objectSpaceType.DataSpace != DataSpace.OSpace) { throw EntityUtil.Argument(Strings.ArgumentMustBeOSpaceType, "objectSpaceType"); } clrType = null; if (BuiltInTypeKind.EntityType == objectSpaceType.BuiltInTypeKind) { clrType = ((ClrEntityType)objectSpaceType).ClrType; } else if (BuiltInTypeKind.ComplexType == objectSpaceType.BuiltInTypeKind) { clrType = ((ClrComplexType)objectSpaceType).ClrType; } return clrType != null; } /// /// Given the canonical primitive type, get the mapping primitive type in the given dataspace /// /// canonical primitive type ///The mapped scalar type internal override PrimitiveType GetMappedPrimitiveType(PrimitiveTypeKind modelType) { PrimitiveType type = null; _primitiveTypeMaps.TryGetType(modelType, null, out type); return type; } ////// Get the OSpace type given the CSpace typename /// /// /// /// ///internal bool TryGetOSpaceType(EdmType cspaceType, out EdmType edmType) { Debug.Assert(DataSpace.CSpace == cspaceType.DataSpace, "DataSpace should be CSpace"); // check if there is an entity or complex type mapping with this name if (BuiltInTypeKind.EntityType == cspaceType.BuiltInTypeKind || BuiltInTypeKind.ComplexType == cspaceType.BuiltInTypeKind) { return _ocMapping.TryGetValue(cspaceType.Identity, out edmType); } return TryGetItem (cspaceType.Identity, out edmType); } /// /// Given the ospace type, returns the fullname of the mapped cspace type. /// Today, since we allow non-default mapping between entity type and complex type, /// this is only possible for entity and complex type. /// /// ///internal static string TryGetMappingCSpaceTypeIdentity(EdmType edmType) { Debug.Assert(DataSpace.OSpace == edmType.DataSpace, "DataSpace must be OSpace"); if (BuiltInTypeKind.EntityType == edmType.BuiltInTypeKind) { return ((ClrEntityType)edmType).CSpaceTypeName; } else if (BuiltInTypeKind.ComplexType == edmType.BuiltInTypeKind) { return ((ClrComplexType)edmType).CSpaceTypeName; } return edmType.Identity; } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Xml.Serialization; using System.Xml; using System.Xml.Schema; using System.Data.Common.Utils; using System.Diagnostics; using System.Collections.ObjectModel; // Using an alias for this because a lot of names in this namespace conflicts with names in metadata using DataClasses = System.Data.Objects.DataClasses; using System.Globalization; using System.Data.Entity; using System.Data.Common; namespace System.Data.Metadata.Edm { ////// Class for representing a collection of items for the object layer. /// Most of the implemetation for actual maintainance of the collection is /// done by ItemCollection /// public sealed partial class ObjectItemCollection : ItemCollection { #region Constructors ////// The ObjectItemCollection that loads metadata from assemblies /// public ObjectItemCollection() : base(DataSpace.OSpace) { foreach (PrimitiveType type in ClrProviderManifest.Instance.GetStoreTypes()) { AddInternal(type); _primitiveTypeMaps.Add(type); } } #endregion #region Fields // Cache for primitive type maps for Edm to provider private readonly CacheForPrimitiveTypes _primitiveTypeMaps = new CacheForPrimitiveTypes(); // Used for tracking the loading of an assembly and its referenced assemblies. Though the value of an entry is bool, the logic represented // by an entry is tri-state, the third state represented by a "missing" entry. To summarize: // 1. Theassociated with an is "true" : Specified and all referenced assemblies have been loaded // 2. The associated with an is "false" : Specified assembly loaded. Its referenced assemblies may not be loaded // 3. The is missing : Specified assembly has not been loaded private Dictionary _knownAssemblies = new Dictionary (); // Dictionary which keeps tracks of oc mapping information - the key is the conceptual name of the type // and the value is the reference to the ospace type private Dictionary _ocMapping = new Dictionary (); private const string EcmPublicKeyToken = "PublicKeyToken=" + AssemblyRef.EcmaPublicKey; private object _loadAssemblyLock = new object(); internal object LoadAssemblyLock { get { return _loadAssemblyLock; } } internal static IList ViewGenerationAssemblies { get { return AssemblyCacheEntry.ViewGenerationAssemblies; } } #endregion #region Methods /// Is the assembly and its referened assemblies not expected to have any metadata internal static bool ShouldFilterAssembly(string fullName) { return (fullName.EndsWith(EcmPublicKeyToken, StringComparison.OrdinalIgnoreCase)); } internal static bool IsSchemaAttributePresent(Assembly assembly) { return assembly.IsDefined(typeof(DataClasses.EdmSchemaAttribute), false /*inherit*/); } internal static bool IsCompiledViewGenAttributePresent(Assembly assembly) { return assembly.IsDefined(typeof(System.Data.Mapping.EntityViewGenerationAttribute), false /*inherit*/); } ////// The method loads the O-space metadata for all the referenced assemblies starting from the given assembly /// in a recursive way. /// The assembly should be from Assembly.GetCallingAssembly via one of our public API's. /// /// assembly whose dependency list we are going to traverse internal void LoadAllReferencedAssemblies(Assembly assembly) { this.LoadAllReferencedAssemblies(assembly, false); } ////// The method loads all the referenced assemblies starting from the given assembly in a recursive way. /// The assembly should be from Assembly.GetCallingAssembly via one of our public API's. /// /// assembly whose dependency list we are going to traverse /// internal void LoadAllReferencedAssemblies(Assembly assembly, bool loadOnlyViewGenInfo) { if (loadOnlyViewGenInfo) { if (!ShouldFilterAssembly(assembly.FullName)) { lock (this) { CollectIfViewGenAssembly(assembly); foreach (AssemblyName asmName in assembly.GetReferencedAssemblies()) { string fullName = asmName.FullName; if (!ShouldFilterAssembly(fullName)) { // filter out "known" assemblies to prevent unnecessary loading Bid.Trace("loadededAssembly='%ls'\n", fullName); Assembly loadedAssembly = AssemblyCacheEntry.SafeLoadReferencedAssembly(fullName); if (loadedAssembly == null) { continue; } CollectIfViewGenAssembly(loadedAssembly); } } } } } else { LoadAssemblyFromCache(this, assembly, true /*loadAllReferencedAssemblies*/); } } /// /// Load metadata from the given assembly /// /// The assembly from which to load metadata ///thrown if assembly argument is null public void LoadFromAssembly(Assembly assembly) { EntityUtil.CheckArgumentNull(assembly, "assembly"); EntityBid.Trace("assembly='%ls'\n", assembly.FullName); LoadAssemblyFromCache(this, assembly, false /*loadAllReferencedAssemblies*/); //Since User called LoadFromAssembly, so we should collect the generated views if present //even if the schema attribute is not present if (IsCompiledViewGenAttributePresent(assembly) && !IsSchemaAttributePresent(assembly) ) { CollectIfViewGenAssembly(assembly); } } /// /// Load metadata from the type's assembly. /// /// The type's assembly is loaded into the OSpace ItemCollection ///true if the type and all its generic arguments are filtered out (did not attempt to load assembly) internal bool LoadAssemblyForType(Type type) { bool result; // InternalLoadFromAssembly will check _knownAssemblies result = LoadAssemblyFromCache(this, type.Assembly, false /*loadAllReferencedAssemblies*/); if (type.IsGenericType) { // recursively load all generic types // interesting code paths are ObjectQuery>, ObjectQuery > foreach (Type t in type.GetGenericArguments()) { result |= LoadAssemblyForType(t); } } return result; } /// /// internal static method to get the relationship name /// /// /// ///internal AssociationType GetRelationshipType(Type entityClrType, string relationshipName, out string fullSearchName) { fullSearchName = relationshipName; AssociationType associationType; if (TryGetItem (relationshipName, out associationType)) { return associationType; } else if (!IsQualifiedName(relationshipName)) { // they send us unqualified relationship names, try to make it fully qualified EntityType entityType; if (TryGetItem (entityClrType.FullName, out entityType)) { // get the c-space namespace string namespaceName = System.Data.EntityModel.SchemaObjectModel.Utils.GetEverythingBeforeLastPeriod(((ClrEntityType)entityType).CSpaceTypeName); fullSearchName = namespaceName + "." + relationshipName; if(TryGetItem (fullSearchName, out associationType)) { return associationType; } } } return null; } /// /// Loads the OSpace types in the assembly and returns them as a dictionary /// /// The assembly to load ///A mapping from names to OSpace EdmTypes private static DictionaryLoadTypesExpensiveWay(Assembly assembly) { Dictionary typesInLoading = null; // If the assembly is not one of the filtered assemblies and has the schema attribute if (!ShouldFilterAssembly(assembly.FullName) && IsSchemaAttributePresent(assembly)) { List errors; Dictionary knownAssemblies = new Dictionary (); AssemblyCacheEntry.LoadAssemblyFromCache(assembly, false /*loadAllReferencedAssemblies*/, knownAssemblies, out typesInLoading, out errors); // Check for errors if (errors.Count != 0) { throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(errors)); } } return typesInLoading; } /// /// internal static method to get the relationship name /// /// /// ///internal static AssociationType GetRelationshipTypeExpensiveWay(Type entityClrType, string relationshipName, out string fullSearchName) { fullSearchName = relationshipName; Dictionary typesInLoading = LoadTypesExpensiveWay(entityClrType.Assembly); if (typesInLoading != null) { EdmType edmType; // Look in typesInLoading for relationship type if (typesInLoading.TryGetValue(relationshipName, out edmType) && Helper.IsRelationshipType(edmType)) { return (AssociationType)edmType; } else if (!IsQualifiedName(relationshipName)) { string namespaceName = GetModelNamespaceForEntityType(typesInLoading, entityClrType); fullSearchName = namespaceName + "." + relationshipName; if (namespaceName != null && typesInLoading.TryGetValue(fullSearchName, out edmType) && Helper.IsRelationshipType(edmType)) { return (AssociationType)edmType; } } } return null; } /// /// internal static method to get all the AssociationTypes from an assembly /// /// The assembly from which to load relationship types ///An enumeration of OSpace AssociationTypes that are present in this assembly internal static IEnumerableGetAllRelationshipTypesExpensiveWay(Assembly assembly) { Dictionary typesInLoading = LoadTypesExpensiveWay(assembly); if (typesInLoading != null) { // Iterate through the EdmTypes looking for AssociationTypes foreach (EdmType edmType in typesInLoading.Values) { if (Helper.IsAssociationType(edmType)) { yield return (AssociationType)edmType; } } } yield break; } private static string GetModelNamespaceForEntityType(Dictionary typesInLoading,Type entityClrType) { EdmType edmType; if(typesInLoading.TryGetValue(entityClrType.FullName, out edmType) && Helper.IsEntityType(edmType)) { return System.Data.EntityModel.SchemaObjectModel.Utils.GetEverythingBeforeLastPeriod(((ClrEntityType)edmType).CSpaceTypeName); } return null; } private static bool IsQualifiedName(string relationshipName) { return relationshipName.Contains("."); } private static bool LoadAssemblyFromCache(ObjectItemCollection objectItemCollection, Assembly assembly, bool loadReferencedAssemblies) { if (ShouldFilterAssembly(assembly.FullName)) { return false; } // Check if its loaded in the cache - if the call is for loading referenced assemblies, make sure that all referenced // assemblies are also loaded bool areReferencedAssembliesLoaded; if (objectItemCollection._knownAssemblies.TryGetValue(assembly, out areReferencedAssembliesLoaded)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false || areReferencedAssembliesLoaded == true) { return true; } } // Check for schema attribute - if we need to load all the referenced assemblies, then we should continue // even if the root assembly doesn't have the attribute present if (!IsSchemaAttributePresent(assembly) && !loadReferencedAssemblies) { return false; } lock (objectItemCollection.LoadAssemblyLock) { // Check after acquiring the lock, since the known assemblies might have got modified // Check if the assembly is already loaded. The reason we need to check if the assembly is already loaded, is that if (objectItemCollection._knownAssemblies.TryGetValue(assembly, out areReferencedAssembliesLoaded)) { // Proceed if only we need to load the referenced assemblies and they are not loaded if (loadReferencedAssemblies == false || areReferencedAssembliesLoaded == true) { return true; } } Dictionary typesInLoading; List errors; Dictionary knownAssemblies; if (objectItemCollection != null) { knownAssemblies = new Dictionary (objectItemCollection._knownAssemblies); } else { knownAssemblies = new Dictionary (); } // Load the assembly from the cache AssemblyCacheEntry.LoadAssemblyFromCache(assembly, loadReferencedAssemblies, knownAssemblies, out typesInLoading, out errors); // Throw if we have encountered errors if (errors.Count != 0) { throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(errors)); } // We can encounter new assemblies, but they may not have any time in them if (typesInLoading.Count != 0) { Debug.Assert(knownAssemblies.Count != objectItemCollection._knownAssemblies.Count, "Since there are no types loaded, some assemblies must have got loaded"); // No errors, so go ahead and add the types and make them readonly // The existence of the loading lock tells us whether we should be thread safe or not, if we need // to be thread safe, then we need to use AtomicAddRange. We don't need to actually use the lock // because the caller should have done it already // Recheck the assemblies added, another list is created just to match up the collection type // taken in by AtomicAddRange() List globalItems = new List (); foreach (EdmType edmType in typesInLoading.Values) { globalItems.Add(edmType); try { // Also populate the ocmapping information if (BuiltInTypeKind.EntityType == edmType.BuiltInTypeKind) { objectItemCollection._ocMapping.Add(((ClrEntityType)edmType).CSpaceTypeName, edmType); } else if (BuiltInTypeKind.ComplexType == edmType.BuiltInTypeKind) { objectItemCollection._ocMapping.Add(((ClrComplexType)edmType).CSpaceTypeName, edmType); } // for rest of the types like relationship type, we do not have oc mapping, so we don't keep // to keep that information } catch (ArgumentException e) { throw new MappingException(Strings.Mapping_CannotMapCLRTypeMultipleTimes(edmType.Identity), e); } } // Create a new ObjectItemCollection and add all the global items to it. // Also copy all the existing items from the existing collection objectItemCollection.AtomicAddRange(globalItems); // Update the value of known assemblies objectItemCollection._knownAssemblies = knownAssemblies; foreach (Assembly loadedAssembly in knownAssemblies.Keys) { CollectIfViewGenAssembly(loadedAssembly); } } } return true; } /// /// Check to see if the assembly has the custom view generation attribute AND /// collect the assembly into the local list if it has cutom attribute. /// /// /// private static void CollectIfViewGenAssembly(Assembly assembly) { if (assembly.IsDefined(typeof(System.Data.Mapping.EntityViewGenerationAttribute), false /*inherit*/)) { if (!AssemblyCacheEntry.ViewGenerationAssemblies.Contains(assembly)) { AssemblyCacheEntry.ViewGenerationAssemblies.Add(assembly); } } } ////// Get the list of primitive types for the given space /// ///public IEnumerable GetPrimitiveTypes() { return _primitiveTypeMaps.GetTypes(); } /// /// The method returns the underlying CLR type for the specified OSpace type argument. /// If the DataSpace of the parameter is not OSpace, an ArgumentException is thrown. /// /// The OSpace type to look up ///The CLR type of the OSpace argument public Type GetClrType(StructuralType objectSpaceType) { Type clrType; if (!this.TryGetClrType(objectSpaceType, out clrType)) { throw EntityUtil.Argument(Strings.FailedToFindClrTypeMapping(objectSpaceType.Identity)); } return clrType; } ////// The method returns the underlying CLR type for the specified OSpace type argument. /// If the DataSpace of the parameter is not OSpace, the method returns false and sets /// the out parameter to null. /// /// The OSpace type to look up /// The CLR type of the OSpace argument ///true on success, false on failure public bool TryGetClrType(StructuralType objectSpaceType, out Type clrType) { EntityUtil.CheckArgumentNull(objectSpaceType, "objectSpaceType"); if (objectSpaceType.DataSpace != DataSpace.OSpace) { throw EntityUtil.Argument(Strings.ArgumentMustBeOSpaceType, "objectSpaceType"); } clrType = null; if (BuiltInTypeKind.EntityType == objectSpaceType.BuiltInTypeKind) { clrType = ((ClrEntityType)objectSpaceType).ClrType; } else if (BuiltInTypeKind.ComplexType == objectSpaceType.BuiltInTypeKind) { clrType = ((ClrComplexType)objectSpaceType).ClrType; } return clrType != null; } /// /// Given the canonical primitive type, get the mapping primitive type in the given dataspace /// /// canonical primitive type ///The mapped scalar type internal override PrimitiveType GetMappedPrimitiveType(PrimitiveTypeKind modelType) { PrimitiveType type = null; _primitiveTypeMaps.TryGetType(modelType, null, out type); return type; } ////// Get the OSpace type given the CSpace typename /// /// /// /// ///internal bool TryGetOSpaceType(EdmType cspaceType, out EdmType edmType) { Debug.Assert(DataSpace.CSpace == cspaceType.DataSpace, "DataSpace should be CSpace"); // check if there is an entity or complex type mapping with this name if (BuiltInTypeKind.EntityType == cspaceType.BuiltInTypeKind || BuiltInTypeKind.ComplexType == cspaceType.BuiltInTypeKind) { return _ocMapping.TryGetValue(cspaceType.Identity, out edmType); } return TryGetItem (cspaceType.Identity, out edmType); } /// /// Given the ospace type, returns the fullname of the mapped cspace type. /// Today, since we allow non-default mapping between entity type and complex type, /// this is only possible for entity and complex type. /// /// ///internal static string TryGetMappingCSpaceTypeIdentity(EdmType edmType) { Debug.Assert(DataSpace.OSpace == edmType.DataSpace, "DataSpace must be OSpace"); if (BuiltInTypeKind.EntityType == edmType.BuiltInTypeKind) { return ((ClrEntityType)edmType).CSpaceTypeName; } else if (BuiltInTypeKind.ComplexType == edmType.BuiltInTypeKind) { return ((ClrComplexType)edmType).CSpaceTypeName; } return edmType.Identity; } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataServiceKeyAttribute.cs
- Decimal.cs
- RSAOAEPKeyExchangeFormatter.cs
- __ComObject.cs
- ApplicationTrust.cs
- BamlResourceDeserializer.cs
- TreeNodeEventArgs.cs
- Collection.cs
- WsdlBuildProvider.cs
- CompoundFileIOPermission.cs
- ExpandCollapseProviderWrapper.cs
- Profiler.cs
- EqualityComparer.cs
- ComponentEditorPage.cs
- ConfigXmlWhitespace.cs
- GlyphsSerializer.cs
- InternalConfigSettingsFactory.cs
- AsnEncodedData.cs
- Pipe.cs
- DesignerExtenders.cs
- TaskScheduler.cs
- WpfKnownType.cs
- SendMessageRecord.cs
- Base64Stream.cs
- xmlsaver.cs
- XmlSchemaInfo.cs
- ReadOnlyCollectionBase.cs
- Clause.cs
- WindowsSecurityToken.cs
- BitStream.cs
- XsltSettings.cs
- AnnouncementEndpointElement.cs
- SubqueryRules.cs
- ListItemsPage.cs
- ReceiveContext.cs
- hwndwrapper.cs
- CollectionType.cs
- BasicHttpBindingElement.cs
- TypeProvider.cs
- uribuilder.cs
- OperationContractGenerationContext.cs
- GeometryGroup.cs
- MatrixTransform.cs
- MD5.cs
- WindowsGrip.cs
- SQLConvert.cs
- QuaternionConverter.cs
- XmlSchemaComplexContentRestriction.cs
- EntitySqlQueryCacheEntry.cs
- ToolboxComponentsCreatedEventArgs.cs
- ClientScriptManager.cs
- TabletDevice.cs
- ExportException.cs
- ComboBox.cs
- TableCellCollection.cs
- OrderedParallelQuery.cs
- KeyValuePair.cs
- EventLogPropertySelector.cs
- UserControlCodeDomTreeGenerator.cs
- SqlDataSourceSelectingEventArgs.cs
- XmlSchemaSimpleContent.cs
- CacheAxisQuery.cs
- GridViewEditEventArgs.cs
- ColorMap.cs
- Visual3D.cs
- XmlTextReader.cs
- DebuggerAttributes.cs
- TypeUtils.cs
- CurrencyWrapper.cs
- EntityConnectionStringBuilder.cs
- QueryTask.cs
- ComEventsInfo.cs
- ValueType.cs
- CounterSample.cs
- GPRECTF.cs
- SqlReferenceCollection.cs
- UDPClient.cs
- ScriptControlDescriptor.cs
- KeySplineConverter.cs
- RowVisual.cs
- XmlTypeAttribute.cs
- metadatamappinghashervisitor.hashsourcebuilder.cs
- XMLSchema.cs
- DispatcherObject.cs
- DataGridViewHitTestInfo.cs
- VarRefManager.cs
- WorkflowInstanceExtensionManager.cs
- ColumnMapCopier.cs
- AnnotationService.cs
- ThreadStaticAttribute.cs
- PathFigureCollectionConverter.cs
- HtmlTableRow.cs
- Int64Storage.cs
- MimeObjectFactory.cs
- CodeIdentifiers.cs
- BaseValidatorDesigner.cs
- DifferencingCollection.cs
- LongAverageAggregationOperator.cs
- SecurityVerifiedMessage.cs
- XamlReaderHelper.cs