コード例 #1
0
        /// <summary>
        /// Load stuff from xml readers - this now includes XmlReader instances created over embedded
        /// resources. See the remarks section below for some useful information.
        /// </summary>
        /// <param name="xmlReaders">A list of XmlReader instances</param>
        /// <param name="dataModelOption">whether this is a entity data model or provider data model</param>
        /// <param name="providerManifest">provider manifest from which the primitive type definition comes from</param>
        /// <param name="itemCollection">item collection to add the item after loading</param>
        /// <param name="computeFilePaths">Indicates whether the method should bother with the file paths; see remarks below</param>
        /// <remarks>
        /// In order to accommodate XmlReaders over artifacts embedded as resources in assemblies, the
        /// notion of a filepath had to be abstracted into a URI. In reality, however, a res:// URI that
        /// points to an embedded resource does not constitute a valid URI (i.e., one that can be parsed
        /// by the System.Uri class in the .NET framework). In such cases, we need to supply a list of
        /// "filepaths" (which includes res:// URIs), instead of having this method create the collection.
        /// This distinction is made by setting the 'computeFilePaths' flags appropriately.
        /// </remarks>
        internal static IList <EdmSchemaError> LoadItems(IEnumerable <XmlReader> xmlReaders,
                                                         IEnumerable <string> sourceFilePaths,
                                                         SchemaDataModelOption dataModelOption,
                                                         DbProviderManifest providerManifest,
                                                         ItemCollection itemCollection,
                                                         bool throwOnError)
        {
            IList <Schema> schemaCollection = null;

            // Parse and validate all the schemas - since we support using now,
            // we need to parse them as a group
            var errorCollection = SchemaManager.ParseAndValidate(xmlReaders, sourceFilePaths,
                                                                 dataModelOption, providerManifest, out schemaCollection);

            // Try to initialize the metadata if there are no errors
            if (MetadataHelper.CheckIfAllErrorsAreWarnings(errorCollection))
            {
                List <EdmSchemaError> errors = LoadItems(providerManifest, schemaCollection, itemCollection);
                foreach (var error in errors)
                {
                    errorCollection.Add(error);
                }
            }
            if (!MetadataHelper.CheckIfAllErrorsAreWarnings(errorCollection) && throwOnError)
            {
                //Future Enhancement: if there is an error, we throw exception with error and warnings.
                //Otherwise the user has no clue to know about warnings.
                throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(errorCollection));
            }
            return(errorCollection);
        }
コード例 #2
0
 internal void ThrowOnNonWarningErrors()
 {
     if (!MetadataHelper.CheckIfAllErrorsAreWarnings(_errors))
     {
         //Future Enhancement: if there is an error, we throw exception with error and warnings.
         //Otherwise the user has no clue to know about warnings.
         throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(_errors));
     }
 }
コード例 #3
0
        /// <summary>
        /// Loads the OSpace types in the assembly and returns them as a dictionary
        /// </summary>
        /// <param name="assembly">The assembly to load</param>
        /// <returns>A mapping from names to OSpace EdmTypes</returns>
        internal static Dictionary <string, EdmType> LoadTypesExpensiveWay(Assembly assembly)
        {
            Dictionary <string, EdmType> typesInLoading = null;

            List <EdmItemError> errors;
            KnownAssembliesSet  knownAssemblies = new KnownAssembliesSet();

            AssemblyCache.LoadAssembly(assembly, false /*loadAllReferencedAssemblies*/,
                                       knownAssemblies, out typesInLoading, out errors);

            // Check for errors
            if (errors.Count != 0)
            {
                throw EntityUtil.InvalidSchemaEncountered(Helper.CombineErrorMessage(errors));
            }

            return(typesInLoading);
        }
コード例 #4
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 == true)
                {
                    // 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 == true)
                    {
                        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()
                    List <GlobalItem> globalItems = new List <GlobalItem>();
                    foreach (EdmType edmType in typesInLoading.Values)
                    {
                        globalItems.Add(edmType);

                        string 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 (Assembly loadedAssembly in knownAssemblies.Assemblies)
                {
                    CollectIfViewGenAssembly(loadedAssembly);
                }

                return(typesInLoading.Count != 0);
            }
        }