コード例 #1
0
        internal virtual void AddLoadedTypes(Dictionary <string, EdmType> typesInLoading)
        {
            List <GlobalItem> items = new List <GlobalItem>();

            foreach (EdmType edmType in typesInLoading.Values)
            {
                items.Add((GlobalItem)edmType);
                string key = "";
                try
                {
                    if (Helper.IsEntityType(edmType))
                    {
                        key = ((ClrEntityType)edmType).CSpaceTypeName;
                        this._ocMapping.Add(key, edmType);
                    }
                    else if (Helper.IsComplexType(edmType))
                    {
                        key = ((ClrComplexType)edmType).CSpaceTypeName;
                        this._ocMapping.Add(key, edmType);
                    }
                    else if (Helper.IsEnumType(edmType))
                    {
                        key = ((ClrEnumType)edmType).CSpaceTypeName;
                        this._ocMapping.Add(key, edmType);
                    }
                }
                catch (ArgumentException ex)
                {
                    throw new MappingException(Strings.Mapping_CannotMapCLRTypeMultipleTimes((object)key), (Exception)ex);
                }
            }
            this.AddRange(items);
        }
コード例 #2
0
        // <summary>
        // A helper method returning the underlying CLR type for the specified OSpace enum or structural type argument.
        // If the DataSpace of the parameter is not OSpace, the method returns false and sets
        // the out parameter to null.
        // </summary>
        // <param name="objectSpaceType"> The OSpace enum type to look up </param>
        // <param name="clrType"> The CLR enum type of the OSpace argument </param>
        // <returns> true on success, false on failure </returns>
        private static bool TryGetClrType(EdmType objectSpaceType, out Type clrType)
        {
            DebugCheck.NotNull(objectSpaceType);

            Debug.Assert(
                objectSpaceType == null || objectSpaceType is StructuralType || objectSpaceType is EnumType,
                "Only enum or structural type expected");

            if (objectSpaceType.DataSpace != DataSpace.OSpace)
            {
                throw new ArgumentException(Strings.ArgumentMustBeOSpaceType, "objectSpaceType");
            }

            clrType = null;

            if (Helper.IsEntityType(objectSpaceType) ||
                Helper.IsComplexType(objectSpaceType) ||
                Helper.IsEnumType(objectSpaceType))
            {
                Debug.Assert(
                    objectSpaceType is ClrEntityType || objectSpaceType is ClrComplexType || objectSpaceType is ClrEnumType,
                    "Unexpected OSpace object type.");

                clrType = objectSpaceType.ClrType;

                Debug.Assert(clrType != null, "ClrType property of ClrEntityType/ClrComplexType/ClrEnumType objects must not be null");
            }

            return(clrType != null);
        }
コード例 #3
0
 internal bool TryGetOSpaceType(EdmType cspaceType, out EdmType edmType)
 {
     if (Helper.IsEntityType(cspaceType) || Helper.IsComplexType(cspaceType) || Helper.IsEnumType(cspaceType))
     {
         return(this._ocMapping.TryGetValue(cspaceType.Identity, out edmType));
     }
     return(this.TryGetItem <EdmType>(cspaceType.Identity, out edmType));
 }
コード例 #4
0
 internal static bool IsStructuralType(EdmType type)
 {
     if (!Helper.IsComplexType(type) && !Helper.IsEntityType(type) && !Helper.IsRelationshipType(type))
     {
         return(Helper.IsRowType((GlobalItem)type));
     }
     return(true);
 }
コード例 #5
0
        /// <summary>
        ///     Creates a structural OSpace type based on CLR type and CSpace type.
        /// </summary>
        /// <param name="type"> CLR type. </param>
        /// <param name="cspaceType"> CSpace Type </param>
        /// <param name="newOSpaceType">
        ///     OSpace type created based on CLR <paramref name="type" /> and <paramref name="cspaceType" />
        /// </param>
        /// <returns>
        ///     <c>true</c> if the type was created successfully. Otherwise <c>false</c> .
        /// </returns>
        private bool TryCreateStructuralType(Type type, StructuralType cspaceType, out EdmType newOSpaceType)
        {
            DebugCheck.NotNull(type);
            DebugCheck.NotNull(cspaceType);

            var referenceResolutionListForCurrentType = new List <Action>();

            newOSpaceType = null;
            Debug.Assert(TypesMatchByConvention(type, cspaceType), "The types passed as parameters don't match by convention.");

            StructuralType ospaceType;

            if (Helper.IsEntityType(cspaceType))
            {
                ospaceType = new ClrEntityType(type, cspaceType.NamespaceName, cspaceType.Name);
            }
            else
            {
                Debug.Assert(Helper.IsComplexType(cspaceType), "Invalid type attribute encountered");
                ospaceType = new ClrComplexType(type, cspaceType.NamespaceName, cspaceType.Name);
            }

            if (cspaceType.BaseType != null)
            {
                if (TypesMatchByConvention(type.BaseType, cspaceType.BaseType))
                {
                    TrackClosure(type.BaseType);
                    referenceResolutionListForCurrentType.Add(
                        () => ospaceType.BaseType = ResolveBaseType((StructuralType)cspaceType.BaseType, type));
                }
                else
                {
                    var message = Strings.Validator_OSpace_Convention_BaseTypeIncompatible(
                        type.BaseType.FullName, type.FullName, cspaceType.BaseType.FullName);
                    SessionData.LoadMessageLogger.LogLoadMessage(message, cspaceType);
                    return(false);
                }
            }

            // Load the properties for this type
            if (!TryCreateMembers(type, cspaceType, ospaceType, referenceResolutionListForCurrentType))
            {
                return(false);
            }

            // Add this to the known type map so we won't try to load it again
            SessionData.TypesInLoading.Add(type.FullName, ospaceType);

            // we only add the referenceResolution to the list unless we structrually matched this type
            foreach (var referenceResolution in referenceResolutionListForCurrentType)
            {
                _referenceResolutions.Add(referenceResolution);
            }

            newOSpaceType = ospaceType;
            return(true);
        }
コード例 #6
0
        /// <summary>Creates a new instance of EdmProperty type.</summary>
        /// <param name="name">Name of the property.</param>
        /// <param name="typeUsage">
        /// Property <see cref="T:System.Data.Entity.Core.Metadata.Edm.TypeUsage" />
        /// </param>
        /// <returns>A new instance of EdmProperty type</returns>
        public static EdmProperty Create(string name, TypeUsage typeUsage)
        {
            Check.NotEmpty(name, nameof(name));
            Check.NotNull <TypeUsage>(typeUsage, nameof(typeUsage));
            EdmType edmType = typeUsage.EdmType;

            if (!Helper.IsPrimitiveType(edmType) && !Helper.IsEnumType(edmType) && !Helper.IsComplexType(edmType))
            {
                throw new ArgumentException(Strings.EdmProperty_InvalidPropertyType((object)edmType.FullName));
            }
            return(new EdmProperty(name, typeUsage));
        }
コード例 #7
0
 private static bool TryGetClrType(EdmType objectSpaceType, out Type clrType)
 {
     if (objectSpaceType.DataSpace != DataSpace.OSpace)
     {
         throw new ArgumentException(Strings.ArgumentMustBeOSpaceType, nameof(objectSpaceType));
     }
     clrType = (Type)null;
     if (Helper.IsEntityType(objectSpaceType) || Helper.IsComplexType(objectSpaceType) || Helper.IsEnumType(objectSpaceType))
     {
         clrType = objectSpaceType.ClrType;
     }
     return(clrType != (Type)null);
 }
コード例 #8
0
        // <summary>
        // Get the OSpace type given the CSpace typename
        // </summary>
        internal bool TryGetOSpaceType(EdmType cspaceType, out EdmType edmType)
        {
            Debug.Assert(DataSpace.CSpace == cspaceType.DataSpace, "DataSpace should be CSpace");

            // check if there is an entity, complex type or enum type mapping with this name
            if (Helper.IsEntityType(cspaceType) ||
                Helper.IsComplexType(cspaceType) ||
                Helper.IsEnumType(cspaceType))
            {
                return(_ocMapping.TryGetValue(cspaceType.Identity, out edmType));
            }

            return(TryGetItem(cspaceType.Identity, out edmType));
        }
コード例 #9
0
        internal ObjectItemLoadingSessionData(
            KnownAssembliesSet knownAssemblies, LockedAssemblyCache lockedAssemblyCache, EdmItemCollection edmItemCollection,
            Action <String> logLoadMessage, object loaderCookie)
        {
            Debug.Assert(
                loaderCookie == null || loaderCookie is Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>,
                "This is a bad loader cookie");

            _typesInLoading      = new Dictionary <string, EdmType>(StringComparer.Ordinal);
            _errors              = new List <EdmItemError>();
            _knownAssemblies     = knownAssemblies;
            _lockedAssemblyCache = lockedAssemblyCache;
            _loadersThatNeedLevel1PostSessionProcessing = new HashSet <ObjectItemAssemblyLoader>();
            _loadersThatNeedLevel2PostSessionProcessing = new HashSet <ObjectItemAssemblyLoader>();
            _edmItemCollection    = edmItemCollection;
            _loadMessageLogger    = new LoadMessageLogger(logLoadMessage);
            _cspaceToOspace       = new Dictionary <EdmType, EdmType>();
            _loaderFactory        = (Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>)loaderCookie;
            _originalLoaderCookie = loaderCookie;
            if (_loaderFactory == ObjectItemConventionAssemblyLoader.Create &&
                _edmItemCollection != null)
            {
                foreach (var entry in _knownAssemblies.GetEntries(_loaderFactory, edmItemCollection))
                {
                    foreach (var type in entry.CacheEntry.TypesInAssembly.OfType <EdmType>())
                    {
                        if (Helper.IsEntityType(type))
                        {
                            var entityType = (ClrEntityType)type;
                            _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(entityType.CSpaceTypeName), entityType);
                        }
                        else if (Helper.IsComplexType(type))
                        {
                            var complexType = (ClrComplexType)type;
                            _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(complexType.CSpaceTypeName), complexType);
                        }
                        else if (Helper.IsEnumType(type))
                        {
                            var enumType = (ClrEnumType)type;
                            _cspaceToOspace.Add(_edmItemCollection.GetItem <EnumType>(enumType.CSpaceTypeName), enumType);
                        }
                        else
                        {
                            Debug.Assert(Helper.IsAssociationType(type));
                            _cspaceToOspace.Add(_edmItemCollection.GetItem <StructuralType>(type.FullName), type);
                        }
                    }
                }
            }
        }
コード例 #10
0
 internal static string TryGetMappingCSpaceTypeIdentity(EdmType edmType)
 {
     if (Helper.IsEntityType(edmType))
     {
         return(((ClrEntityType)edmType).CSpaceTypeName);
     }
     if (Helper.IsComplexType(edmType))
     {
         return(((ClrComplexType)edmType).CSpaceTypeName);
     }
     if (Helper.IsEnumType(edmType))
     {
         return(((ClrEnumType)edmType).CSpaceTypeName);
     }
     return(edmType.Identity);
 }
コード例 #11
0
        /// <summary>
        /// Creates a new instance of EdmProperty type.
        /// </summary>
        /// <param name="name">Name of the property.</param>
        /// <param name="typeUsage">
        /// Property <see cref="TypeUsage" />
        /// </param>
        /// <returns>A new instance of EdmProperty type</returns>
        public static EdmProperty Create(string name, TypeUsage typeUsage)
        {
            Check.NotEmpty(name, "name");
            Check.NotNull(typeUsage, "typeUsage");

            var edmType = typeUsage.EdmType;

            if (!(Helper.IsPrimitiveType(edmType) ||
                  Helper.IsEnumType(edmType) ||
                  Helper.IsComplexType(edmType)))
            {
                throw new ArgumentException(Strings.EdmProperty_InvalidPropertyType(edmType.FullName));
            }

            return(new EdmProperty(name, typeUsage));
        }
コード例 #12
0
 internal ObjectItemLoadingSessionData(
     KnownAssembliesSet knownAssemblies,
     LockedAssemblyCache lockedAssemblyCache,
     EdmItemCollection edmItemCollection,
     Action <string> logLoadMessage,
     object loaderCookie)
 {
     this._typesInLoading       = new Dictionary <string, EdmType>((IEqualityComparer <string>)StringComparer.Ordinal);
     this._errors               = new List <EdmItemError>();
     this._knownAssemblies      = knownAssemblies;
     this._lockedAssemblyCache  = lockedAssemblyCache;
     this._edmItemCollection    = edmItemCollection;
     this._loadMessageLogger    = new LoadMessageLogger(logLoadMessage);
     this._cspaceToOspace       = new Dictionary <EdmType, EdmType>();
     this._loaderFactory        = (Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>)loaderCookie;
     this._originalLoaderCookie = loaderCookie;
     if (!(this._loaderFactory == new Func <Assembly, ObjectItemLoadingSessionData, ObjectItemAssemblyLoader>(ObjectItemConventionAssemblyLoader.Create)) || this._edmItemCollection == null)
     {
         return;
     }
     foreach (KnownAssemblyEntry entry in this._knownAssemblies.GetEntries((object)this._loaderFactory, edmItemCollection))
     {
         foreach (EdmType edmType in entry.CacheEntry.TypesInAssembly.OfType <EdmType>())
         {
             if (Helper.IsEntityType(edmType))
             {
                 ClrEntityType clrEntityType = (ClrEntityType)edmType;
                 this._cspaceToOspace.Add((EdmType)this._edmItemCollection.GetItem <StructuralType>(clrEntityType.CSpaceTypeName), (EdmType)clrEntityType);
             }
             else if (Helper.IsComplexType(edmType))
             {
                 ClrComplexType clrComplexType = (ClrComplexType)edmType;
                 this._cspaceToOspace.Add((EdmType)this._edmItemCollection.GetItem <StructuralType>(clrComplexType.CSpaceTypeName), (EdmType)clrComplexType);
             }
             else if (Helper.IsEnumType(edmType))
             {
                 ClrEnumType clrEnumType = (ClrEnumType)edmType;
                 this._cspaceToOspace.Add((EdmType)this._edmItemCollection.GetItem <EnumType>(clrEnumType.CSpaceTypeName), (EdmType)clrEnumType);
             }
             else
             {
                 this._cspaceToOspace.Add((EdmType)this._edmItemCollection.GetItem <StructuralType>(edmType.FullName), edmType);
             }
         }
     }
 }
コード例 #13
0
        // <summary>
        // 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.
        // </summary>
        internal static string TryGetMappingCSpaceTypeIdentity(EdmType edmType)
        {
            Debug.Assert(DataSpace.OSpace == edmType.DataSpace, "DataSpace must be OSpace");

            if (Helper.IsEntityType(edmType))
            {
                return(((ClrEntityType)edmType).CSpaceTypeName);
            }
            else if (Helper.IsComplexType(edmType))
            {
                return(((ClrComplexType)edmType).CSpaceTypeName);
            }
            else if (Helper.IsEnumType(edmType))
            {
                return(((ClrEnumType)edmType).CSpaceTypeName);
            }

            return(edmType.Identity);
        }
コード例 #14
0
        internal virtual void AddLoadedTypes(Dictionary <string, EdmType> typesInLoading)
        {
            DebugCheck.NotNull(typesInLoading);

            var globalItems = new List <GlobalItem>();

            foreach (var edmType in typesInLoading.Values)
            {
                globalItems.Add(edmType);

                var cspaceTypeName = "";
                try
                {
                    // Also populate the ocmapping information
                    if (Helper.IsEntityType(edmType))
                    {
                        cspaceTypeName = ((ClrEntityType)edmType).CSpaceTypeName;
                        _ocMapping.Add(cspaceTypeName, edmType);
                    }
                    else if (Helper.IsComplexType(edmType))
                    {
                        cspaceTypeName = ((ClrComplexType)edmType).CSpaceTypeName;
                        _ocMapping.Add(cspaceTypeName, edmType);
                    }
                    else if (Helper.IsEnumType(edmType))
                    {
                        cspaceTypeName = ((ClrEnumType)edmType).CSpaceTypeName;
                        _ocMapping.Add(cspaceTypeName, edmType);
                    }
                    // for the rest of the types like a relationship type, we do not have oc mapping,
                    // so we don't keep that information
                }
                catch (ArgumentException e)
                {
                    throw new MappingException(Strings.Mapping_CannotMapCLRTypeMultipleTimes(cspaceTypeName), e);
                }
            }

            // Create a new ObjectItemCollection and add all the global items to it.
            // Also copy all the existing items from the existing collection
            AddRange(globalItems);
        }
コード例 #15
0
        private bool TryFindComplexProperties(
            Type type,
            StructuralType cspaceType,
            StructuralType ospaceType,
            IEnumerable <PropertyInfo> clrProperties,
            List <Action> referenceResolutionListForCurrentType)
        {
            List <KeyValuePair <EdmProperty, PropertyInfo> > keyValuePairList = new List <KeyValuePair <EdmProperty, PropertyInfo> >();

            foreach (EdmProperty edmProperty in cspaceType.GetDeclaredOnlyMembers <EdmProperty>().Where <EdmProperty>((Func <EdmProperty, bool>)(m => Helper.IsComplexType(m.TypeUsage.EdmType))))
            {
                EdmProperty  cspaceProperty = edmProperty;
                PropertyInfo propertyInfo   = clrProperties.FirstOrDefault <PropertyInfo>((Func <PropertyInfo, bool>)(p => OSpaceTypeFactory.MemberMatchesByConvention(p, (EdmMember)cspaceProperty)));
                if (propertyInfo != (PropertyInfo)null)
                {
                    keyValuePairList.Add(new KeyValuePair <EdmProperty, PropertyInfo>(cspaceProperty, propertyInfo));
                }
                else
                {
                    this.LogLoadMessage(Strings.Validator_OSpace_Convention_MissingRequiredProperty((object)cspaceProperty.Name, (object)type.FullName), (EdmType)cspaceType);
                    return(false);
                }
            }
            foreach (KeyValuePair <EdmProperty, PropertyInfo> keyValuePair in keyValuePairList)
            {
                this.TrackClosure(keyValuePair.Value.PropertyType);
                StructuralType ot   = ospaceType;
                EdmProperty    cp   = keyValuePair.Key;
                PropertyInfo   clrp = keyValuePair.Value;
                referenceResolutionListForCurrentType.Add((Action)(() => this.CreateAndAddComplexType(type, ot, cp, clrp)));
            }
            return(true);
        }
コード例 #16
0
        // <summary>
        // Retrieves a mapping to CLR type for the given EDM type. Assumes the MetadataWorkspace has no
        // </summary>
        internal static ObjectTypeMapping GetObjectMapping(EdmType type, MetadataWorkspace workspace)
        {
            // Check if the workspace has cspace item collection registered with it. If not, then its a case
            // of public materializer trying to create objects from PODR or EntityDataReader with no context.
            ItemCollection collection;

            if (workspace.TryGetItemCollection(DataSpace.CSpace, out collection))
            {
                return((ObjectTypeMapping)workspace.GetMap(type, DataSpace.OCSpace));
            }
            else
            {
                EdmType ospaceType;
                EdmType cspaceType;
                // If its a case of EntityDataReader with no context, the typeUsage which is passed in must contain
                // a cspace type. We need to look up an OSpace type in the ospace item collection and then create
                // ocMapping
                if (type.DataSpace
                    == DataSpace.CSpace)
                {
                    // if its a primitive type, then the names will be different for CSpace type and OSpace type
                    if (Helper.IsPrimitiveType(type))
                    {
                        ospaceType = workspace.GetMappedPrimitiveType(((PrimitiveType)type).PrimitiveTypeKind, DataSpace.OSpace);
                    }
                    else
                    {
                        // Metadata will throw if there is no item with this identity present.
                        // Is this exception fine or does object materializer code wants to wrap and throw a new exception
                        ospaceType = workspace.GetItem <EdmType>(type.FullName, DataSpace.OSpace);
                    }
                    cspaceType = type;
                }
                else
                {
                    // In case of PODR, there is no cspace at all. We must create a fake ocmapping, with ospace types
                    // on both the ends
                    ospaceType = type;
                    cspaceType = type;
                }

                // This condition must be hit only when someone is trying to materialize a legacy data reader and we
                // don't have the CSpace metadata.
                if (!Helper.IsPrimitiveType(ospaceType) &&
                    !Helper.IsEntityType(ospaceType) &&
                    !Helper.IsComplexType(ospaceType))
                {
                    throw new NotSupportedException(Strings.Materializer_UnsupportedType);
                }

                ObjectTypeMapping typeMapping;

                if (Helper.IsPrimitiveType(ospaceType))
                {
                    typeMapping = new ObjectTypeMapping(ospaceType, cspaceType);
                }
                else
                {
                    typeMapping = DefaultObjectMappingItemCollection.LoadObjectMapping(cspaceType, ospaceType, null);
                }

                return(typeMapping);
            }
        }
コード例 #17
0
ファイル: TypeUsage.cs プロジェクト: jwanagel/jjwtest
        /// <summary>
        ///     Returns a Model type usage for a provider type
        /// </summary>
        /// <returns> model (CSpace) type usage </returns>
        internal TypeUsage GetModelTypeUsage()
        {
            if (_modelTypeUsage == null)
            {
                var edmType = EdmType;

                // If the edm type is already a cspace type, return the same type
                if (edmType.DataSpace == DataSpace.CSpace ||
                    edmType.DataSpace == DataSpace.OSpace)
                {
                    return(this);
                }

                TypeUsage result;
                if (Helper.IsRowType(edmType))
                {
                    var sspaceRowType = (RowType)edmType;
                    var properties    = new EdmProperty[sspaceRowType.Properties.Count];
                    for (var i = 0; i < properties.Length; i++)
                    {
                        var sspaceProperty = sspaceRowType.Properties[i];
                        var newTypeUsage   = sspaceProperty.TypeUsage.GetModelTypeUsage();
                        properties[i] = new EdmProperty(sspaceProperty.Name, newTypeUsage);
                    }
                    var edmRowType = new RowType(properties, sspaceRowType.InitializerMetadata);
                    result = Create(edmRowType, Facets);
                }
                else if (Helper.IsCollectionType(edmType))
                {
                    var sspaceCollectionType = ((CollectionType)edmType);
                    var newTypeUsage         = sspaceCollectionType.TypeUsage.GetModelTypeUsage();
                    result = Create(new CollectionType(newTypeUsage), Facets);
                }
                else if (Helper.IsRefType(edmType))
                {
                    Debug.Assert(((RefType)edmType).ElementType.DataSpace == DataSpace.CSpace);
                    result = this;
                }
                else if (Helper.IsPrimitiveType(edmType))
                {
                    result = ((PrimitiveType)edmType).ProviderManifest.GetEdmType(this);

                    if (result == null)
                    {
                        throw new ProviderIncompatibleException(Strings.Mapping_ProviderReturnsNullType(ToString()));
                    }

                    if (!TypeSemantics.IsNullable(this))
                    {
                        result = Create(
                            result.EdmType,
                            OverrideFacetValues(
                                result.Facets,
                                new FacetValues
                        {
                            Nullable = false
                        }));
                    }
                }
                else if (Helper.IsEntityTypeBase(edmType) ||
                         Helper.IsComplexType(edmType))
                {
                    result = this;
                }
                else
                {
                    Debug.Assert(false, "Unexpected type found in entity data reader");
                    return(null);
                }
                Interlocked.CompareExchange(ref _modelTypeUsage, result, null);
            }
            return(_modelTypeUsage);
        }
コード例 #18
0
        private static bool LoadAssemblyFromCache(
            ObjectItemCollection objectItemCollection, Assembly assembly,
            bool loadReferencedAssemblies, EdmItemCollection edmItemCollection, Action <String> logLoadMessage)
        {
            // Check if its loaded in the cache - if the call is for loading referenced assemblies, make sure that all referenced
            // assemblies are also loaded
            KnownAssemblyEntry entry;

            if (objectItemCollection._knownAssemblies.TryGetKnownAssembly(
                    assembly, objectItemCollection._loaderCookie, edmItemCollection, out entry))
            {
                // Proceed if only we need to load the referenced assemblies and they are not loaded
                if (loadReferencedAssemblies == false)
                {
                    // don't say we loaded anything, unless we actually did before
                    return(entry.CacheEntry.TypesInAssembly.Count != 0);
                }
                else if (entry.ReferencedAssembliesAreLoaded)
                {
                    // this assembly was part of a all hands reference search
                    return(true);
                }
            }

            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.TryGetKnownAssembly(
                        assembly, objectItemCollection._loaderCookie, edmItemCollection, out entry))
                {
                    // Proceed if only we need to load the referenced assemblies and they are not loaded
                    if (loadReferencedAssemblies == false ||
                        entry.ReferencedAssembliesAreLoaded)
                    {
                        return(true);
                    }
                }

                Dictionary <string, EdmType> typesInLoading;
                List <EdmItemError>          errors;
                KnownAssembliesSet           knownAssemblies;

                if (objectItemCollection != null)
                {
                    knownAssemblies = new KnownAssembliesSet(objectItemCollection._knownAssemblies);
                }
                else
                {
                    knownAssemblies = new KnownAssembliesSet();
                }

                // Load the assembly from the cache
                AssemblyCache.LoadAssembly(
                    assembly, loadReferencedAssemblies, knownAssemblies, edmItemCollection, logLoadMessage,
                    ref objectItemCollection._loaderCookie, 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)
                {
                    // 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()
                    var globalItems = new List <GlobalItem>();
                    foreach (var edmType in typesInLoading.Values)
                    {
                        globalItems.Add(edmType);

                        var cspaceTypeName = "";
                        try
                        {
                            // Also populate the ocmapping information
                            if (Helper.IsEntityType(edmType))
                            {
                                cspaceTypeName = ((ClrEntityType)edmType).CSpaceTypeName;
                                objectItemCollection._ocMapping.Add(cspaceTypeName, edmType);
                            }
                            else if (Helper.IsComplexType(edmType))
                            {
                                cspaceTypeName = ((ClrComplexType)edmType).CSpaceTypeName;
                                objectItemCollection._ocMapping.Add(cspaceTypeName, edmType);
                            }
                            else if (Helper.IsEnumType(edmType))
                            {
                                cspaceTypeName = ((ClrEnumType)edmType).CSpaceTypeName;
                                objectItemCollection._ocMapping.Add(cspaceTypeName, edmType);
                            }
                            // for the rest of the types like a relationship type, we do not have oc mapping,
                            // so we don't keep that information
                        }
                        catch (ArgumentException e)
                        {
                            throw new MappingException(Strings.Mapping_CannotMapCLRTypeMultipleTimes(cspaceTypeName), 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 (var loadedAssembly in knownAssemblies.Assemblies)
                {
                    CollectIfViewGenAssembly(loadedAssembly);
                }

                return(typesInLoading.Count != 0);
            }
        }
コード例 #19
0
        private bool TryFindComplexProperties(
            Type type, StructuralType cspaceType, StructuralType ospaceType, PropertyInfo[] clrProperties,
            List <Action> referenceResolutionListForCurrentType)
        {
            var typeClosureToTrack =
                new List <KeyValuePair <EdmProperty, PropertyInfo> >();

            foreach (
                var cspaceProperty in cspaceType.GetDeclaredOnlyMembers <EdmProperty>().Where(m => Helper.IsComplexType(m.TypeUsage.EdmType))
                )
            {
                var clrProperty = clrProperties.FirstOrDefault(p => MemberMatchesByConvention(p, cspaceProperty));
                if (clrProperty != null)
                {
                    typeClosureToTrack.Add(
                        new KeyValuePair <EdmProperty, PropertyInfo>(
                            cspaceProperty, clrProperty));
                }
                else
                {
                    var message = Strings.Validator_OSpace_Convention_MissingRequiredProperty(cspaceProperty.Name, type.FullName);
                    LogLoadMessage(message, cspaceType);
                    return(false);
                }
            }

            foreach (var typeToTrack in typeClosureToTrack)
            {
                TrackClosure(typeToTrack.Value.PropertyType);
                // prevent the lifting of these closure variables
                var ot   = ospaceType;
                var cp   = typeToTrack.Key;
                var clrp = typeToTrack.Value;
                referenceResolutionListForCurrentType.Add(() => CreateAndAddComplexType(type, ot, cp, clrp));
            }

            return(true);
        }
コード例 #20
0
        internal static ObjectTypeMapping GetObjectMapping(
            EdmType type,
            MetadataWorkspace workspace)
        {
            ItemCollection collection;

            if (workspace.TryGetItemCollection(DataSpace.CSpace, out collection))
            {
                return((ObjectTypeMapping)workspace.GetMap((GlobalItem)type, DataSpace.OCSpace));
            }
            EdmType edmType;
            EdmType cdmType;

            if (type.DataSpace == DataSpace.CSpace)
            {
                edmType = !Helper.IsPrimitiveType(type) ? workspace.GetItem <EdmType>(type.FullName, DataSpace.OSpace) : (EdmType)workspace.GetMappedPrimitiveType(((PrimitiveType)type).PrimitiveTypeKind, DataSpace.OSpace);
                cdmType = type;
            }
            else
            {
                edmType = type;
                cdmType = type;
            }
            if (!Helper.IsPrimitiveType(edmType) && !Helper.IsEntityType(edmType) && !Helper.IsComplexType(edmType))
            {
                throw new NotSupportedException(Strings.Materializer_UnsupportedType);
            }
            return(!Helper.IsPrimitiveType(edmType) ? DefaultObjectMappingItemCollection.LoadObjectMapping(cdmType, edmType, (DefaultObjectMappingItemCollection)null) : new ObjectTypeMapping(edmType, cdmType));
        }