internal FunctionImportMappingComposable(
            EdmFunction functionImport,
            EdmFunction targetFunction,
            List<Tuple<StructuralType, List<StorageConditionPropertyMapping>, List<StoragePropertyMapping>>> structuralTypeMappings,
            EdmProperty[] targetFunctionKeys,
            StorageMappingItemCollection mappingItemCollection,
            string sourceLocation,
            LineInfo lineInfo) 
            : base(functionImport, targetFunction)
        {
            EntityUtil.CheckArgumentNull(mappingItemCollection, "mappingItemCollection");
            Debug.Assert(functionImport.IsComposableAttribute, "functionImport.IsComposableAttribute");
            Debug.Assert(targetFunction.IsComposableAttribute, "targetFunction.IsComposableAttribute");
            Debug.Assert(functionImport.EntitySet == null || structuralTypeMappings != null, "Function import returning entities must have structuralTypeMappings.");
            Debug.Assert(structuralTypeMappings == null || structuralTypeMappings.Count > 0, "Non-null structuralTypeMappings must not be empty.");
            EdmType resultType;
            Debug.Assert(
                structuralTypeMappings != null ||
                MetadataHelper.TryGetFunctionImportReturnType<EdmType>(functionImport, 0, out resultType) && TypeSemantics.IsScalarType(resultType),
                "Either type mappings should be specified or the function import should be Collection(Scalar).");
            Debug.Assert(functionImport.EntitySet == null || targetFunctionKeys != null, "Keys must be inferred for a function import returning entities.");
            Debug.Assert(targetFunctionKeys == null || targetFunctionKeys.Length > 0, "Keys must be null or non-empty.");

            m_mappingItemCollection = mappingItemCollection;
            // We will use these parameters to target s-space function calls in the generated command tree. 
            // Since enums don't exist in s-space we need to use the underlying type.
            m_commandParameters = functionImport.Parameters.Select(p => TypeHelpers.GetPrimitiveTypeUsageForScalar(p.TypeUsage).Parameter(p.Name)).ToArray();
            m_structuralTypeMappings = structuralTypeMappings;
            m_targetFunctionKeys = targetFunctionKeys;
            m_sourceLocation = sourceLocation;
            m_lineInfo = lineInfo;
        }
Esempio n. 2
0
        internal FunctionImportMappingComposable(
            EdmFunction functionImport,
            EdmFunction targetFunction,
            List <Tuple <StructuralType, List <StorageConditionPropertyMapping>, List <StoragePropertyMapping> > > structuralTypeMappings,
            EdmProperty[] targetFunctionKeys,
            StorageMappingItemCollection mappingItemCollection,
            string sourceLocation,
            LineInfo lineInfo)
            : base(functionImport, targetFunction)
        {
            EntityUtil.CheckArgumentNull(mappingItemCollection, "mappingItemCollection");
            Debug.Assert(functionImport.IsComposableAttribute, "functionImport.IsComposableAttribute");
            Debug.Assert(targetFunction.IsComposableAttribute, "targetFunction.IsComposableAttribute");
            Debug.Assert(functionImport.EntitySet == null || structuralTypeMappings != null, "Function import returning entities must have structuralTypeMappings.");
            Debug.Assert(structuralTypeMappings == null || structuralTypeMappings.Count > 0, "Non-null structuralTypeMappings must not be empty.");
            EdmType resultType;

            Debug.Assert(
                structuralTypeMappings != null ||
                MetadataHelper.TryGetFunctionImportReturnType <EdmType>(functionImport, 0, out resultType) && TypeSemantics.IsScalarType(resultType),
                "Either type mappings should be specified or the function import should be Collection(Scalar).");
            Debug.Assert(functionImport.EntitySet == null || targetFunctionKeys != null, "Keys must be inferred for a function import returning entities.");
            Debug.Assert(targetFunctionKeys == null || targetFunctionKeys.Length > 0, "Keys must be null or non-empty.");

            m_mappingItemCollection = mappingItemCollection;
            // We will use these parameters to target s-space function calls in the generated command tree.
            // Since enums don't exist in s-space we need to use the underlying type.
            m_commandParameters      = functionImport.Parameters.Select(p => TypeHelpers.GetPrimitiveTypeUsageForScalar(p.TypeUsage).Parameter(p.Name)).ToArray();
            m_structuralTypeMappings = structuralTypeMappings;
            m_targetFunctionKeys     = targetFunctionKeys;
            m_sourceLocation         = sourceLocation;
            m_lineInfo = lineInfo;
        }
 /// <summary>
 /// Returns all mapping fragments for the given entity set's types and their parent types.
 /// </summary>
  internal static IEnumerable<StorageTypeMapping> GetMappingsForEntitySetAndSuperTypes(StorageMappingItemCollection mappingCollection, EntityContainer container, EntitySetBase entitySet, EntityTypeBase childEntityType)
  {
      return MetadataHelper.GetTypeAndParentTypesOf(childEntityType, mappingCollection.EdmItemCollection, true /*includeAbstractTypes*/).SelectMany(
          edmType => 
              edmType.EdmEquals(childEntityType) ? 
                GetMappingsForEntitySetAndType(mappingCollection, container, entitySet, (edmType as EntityTypeBase))
              : GetIsTypeOfMappingsForEntitySetAndType(mappingCollection, container, entitySet, (edmType as EntityTypeBase), childEntityType)
          ).ToList();
  }
 /// <summary>
 /// Returns mappings for the given set/type only if the mapping applies also to childEntittyType either via IsTypeOf or explicitly specifying multiple types in mapping fragments.
 /// </summary>
 private static IEnumerable<StorageTypeMapping> GetIsTypeOfMappingsForEntitySetAndType(StorageMappingItemCollection mappingCollection, EntityContainer container, EntitySetBase entitySet, EntityTypeBase entityType, EntityTypeBase childEntityType)
 {
     foreach (var mapping in GetMappingsForEntitySetAndType(mappingCollection, container, entitySet, entityType))
     {
         if (mapping.IsOfTypes.Any(parentType => parentType.IsAssignableFrom(childEntityType)) || mapping.Types.Contains(childEntityType))
         {
             yield return mapping;
         }
     }
 }      
            internal ViewDictionary(StorageMappingItemCollection storageMappingItemCollection, 
                            out Dictionary<EntitySetBase, GeneratedView> userDefinedQueryViewsDict,
                            out Dictionary<OfTypeQVCacheKey, GeneratedView> userDefinedQueryViewsOfTypeDict)
            {
                this.m_storageMappingItemCollection = storageMappingItemCollection;
                this.m_generatedViewsMemoizer = new Memoizer<EntityContainer, Dictionary<EntitySetBase, GeneratedView>>(SerializedGetGeneratedViews, null);
                this.m_generatedViewOfTypeMemoizer = new Memoizer<OfTypeQVCacheKey, GeneratedView>(SerializedGeneratedViewOfType, OfTypeQVCacheKey.PairComparer.Instance);

                userDefinedQueryViewsDict = new Dictionary<EntitySetBase, GeneratedView>(EqualityComparer<EntitySetBase>.Default);
                userDefinedQueryViewsOfTypeDict = new Dictionary<OfTypeQVCacheKey, GeneratedView>(OfTypeQVCacheKey.PairComparer.Instance);

                TryGetUserDefinedQueryView = userDefinedQueryViewsDict.TryGetValue;
                TryGetUserDefinedQueryViewOfType = userDefinedQueryViewsOfTypeDict.TryGetValue;
            }
            internal ViewDictionary(StorageMappingItemCollection storageMappingItemCollection,
                                    out Dictionary <EntitySetBase, GeneratedView> userDefinedQueryViewsDict,
                                    out Dictionary <OfTypeQVCacheKey, GeneratedView> userDefinedQueryViewsOfTypeDict)
            {
                this.m_storageMappingItemCollection = storageMappingItemCollection;
                this.m_generatedViewsMemoizer       = new Memoizer <EntityContainer, Dictionary <EntitySetBase, GeneratedView> >(SerializedGetGeneratedViews, null);
                this.m_generatedViewOfTypeMemoizer  = new Memoizer <OfTypeQVCacheKey, GeneratedView>(SerializedGeneratedViewOfType, OfTypeQVCacheKey.PairComparer.Instance);

                userDefinedQueryViewsDict       = new Dictionary <EntitySetBase, GeneratedView>(EqualityComparer <EntitySetBase> .Default);
                userDefinedQueryViewsOfTypeDict = new Dictionary <OfTypeQVCacheKey, GeneratedView>(OfTypeQVCacheKey.PairComparer.Instance);

                TryGetUserDefinedQueryView       = userDefinedQueryViewsDict.TryGetValue;
                TryGetUserDefinedQueryViewOfType = userDefinedQueryViewsOfTypeDict.TryGetValue;
            }
        internal static IEnumerable<StorageTypeMapping> GetMappingsForEntitySetAndType(StorageMappingItemCollection mappingCollection, EntityContainer container, EntitySetBase entitySet, EntityTypeBase entityType)
        {
            Debug.Assert(entityType != null, "EntityType parameter should not be null.");
            StorageEntityContainerMapping containerMapping = GetEntityContainerMap(mappingCollection, container);
            StorageSetMapping extentMap = containerMapping.GetSetMapping(entitySet.Name);

            //The Set may have no mapping
            if (extentMap != null)
            {
                //for each mapping fragment of Type we are interested in within the given set
                //Check use of IsOfTypes in Code review
                foreach (StorageTypeMapping typeMap in extentMap.TypeMappings.Where(map => map.Types.Union(map.IsOfTypes).Contains(entityType)))
                {
                    yield return typeMap;
                }
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Creates the MetadataWorkspace for the given context type and base context type.
        /// </summary>
        /// <param name="contextType">The type of the context.</param>
        /// <param name="baseContextType">The base context type (DbContext or ObjectContext).</param>
        /// <returns>The generated <see cref="MetadataWorkspace"/></returns>
        public static MetadataWorkspace CreateMetadataWorkspaceFromResources(Type contextType, Type baseContextType)
        {
            // get the set of embedded mapping resources for the target assembly and create
            // a metadata workspace info for each group
            IEnumerable <string> metadataResourcePaths         = FindMetadataResources(contextType.Assembly);
            IEnumerable <MetadataWorkspaceInfo> workspaceInfos = GetMetadataWorkspaceInfos(metadataResourcePaths);

            // Search for the correct EntityContainer by name and if found, create
            // a comlete MetadataWorkspace and return it
            foreach (var workspaceInfo in workspaceInfos)
            {
                EdmItemCollection edmItemCollection = new EdmItemCollection(workspaceInfo.Csdl);

                Type currentType = contextType;
                while (currentType != baseContextType && currentType != typeof(object))
                {
                    EntityContainer container;
                    if (edmItemCollection.TryGetEntityContainer(currentType.Name, out container))
                    {
                        StoreItemCollection store = new StoreItemCollection(workspaceInfo.Ssdl);
#if DBCONTEXT // This actually means EF6+
                        MetadataWorkspace workspace = new MetadataWorkspace(
                            () => edmItemCollection,
                            () => store,
                            () => new StorageMappingItemCollection(edmItemCollection, store, workspaceInfo.Msl),
                            () => new ObjectItemCollection());
#else // EF4
                        StorageMappingItemCollection mapping   = new StorageMappingItemCollection(edmItemCollection, store, workspaceInfo.Msl);
                        MetadataWorkspace            workspace = new MetadataWorkspace();
                        workspace.RegisterItemCollection(edmItemCollection);
                        workspace.RegisterItemCollection(store);
                        workspace.RegisterItemCollection(mapping);
                        workspace.RegisterItemCollection(new ObjectItemCollection());
#endif
                        return(workspace);
                    }

                    currentType = currentType.BaseType;
                }
            }
            return(null);
        }
        internal static IEnumerable<StorageEntityTypeModificationFunctionMapping> GetModificationFunctionMappingsForEntitySetAndType(StorageMappingItemCollection mappingCollection, EntityContainer container, EntitySetBase entitySet, EntityTypeBase entityType)
        {
            StorageEntityContainerMapping containerMapping = GetEntityContainerMap(mappingCollection, container);

            StorageSetMapping extentMap = containerMapping.GetSetMapping(entitySet.Name);
            StorageEntitySetMapping entitySetMapping = extentMap as StorageEntitySetMapping;

            //The Set may have no mapping
            if (entitySetMapping != null)
            {
                if (entitySetMapping != null) //could be association set mapping
                {
                    foreach (var v in entitySetMapping.ModificationFunctionMappings.Where(functionMap => functionMap.EntityType.Equals(entityType)))
                    {
                        yield return v;
                    }
                }
            }

        }
        public static LegacyMetadata.MetadataWorkspace ToLegacyMetadataWorkspace(this MetadataWorkspace metadataWorkspace)
        {
            Debug.Assert(metadataWorkspace != null, "metadataWorkspace != null");

            // The cloned workspace is supposed to be used only by provider. Therefore we only care about SSpace.
            // For CSpace and C-S mapping we register dummy item collections just to make the workspace checks pass.
            var legacyStoreItemCollection =
                ((StoreItemCollection)metadataWorkspace.GetItemCollection(DataSpace.SSpace)).ToLegacyStoreItemCollection();

            var version = EntityFrameworkVersion.DoubleToVersion(legacyStoreItemCollection.StoreSchemaVersion);

            var legacyEdmItemCollection = GetLegacyEdmItemCollection(version);

            var legacyWorkspace = new LegacyMetadata.MetadataWorkspace();

            legacyWorkspace.RegisterItemCollection(legacyEdmItemCollection);
            legacyWorkspace.RegisterItemCollection(legacyStoreItemCollection);

            var msl = string.Format(
                CultureInfo.InvariantCulture,
                MslTemplate,
                SchemaManager.GetMSLNamespaceName(version),
                legacyStoreItemCollection.GetItems <LegacyMetadata.EntityContainer>().Single().Name);

            using (var stringReader = new StringReader(msl))
            {
                using (var reader = XmlReader.Create(stringReader))
                {
                    var legacyMappingItemCollection =
                        new LegacyMapping.StorageMappingItemCollection(
                            legacyEdmItemCollection,
                            legacyStoreItemCollection,
                            new[] { reader });

                    legacyWorkspace.RegisterItemCollection(legacyMappingItemCollection);
                }
            }

            return(legacyWorkspace);
        }
        public static LegacyMetadata.MetadataWorkspace ToLegacyMetadataWorkspace(this MetadataWorkspace metadataWorkspace)
        {
            Debug.Assert(metadataWorkspace != null, "metadataWorkspace != null");

            // The cloned workspace is supposed to be used only by provider. Therefore we only care about SSpace.
            // For CSpace and C-S mapping we register dummy item collections just to make the workspace checks pass.
            var legacyStoreItemCollection =
                ((StoreItemCollection)metadataWorkspace.GetItemCollection(DataSpace.SSpace)).ToLegacyStoreItemCollection();

            var version = EntityFrameworkVersion.DoubleToVersion(legacyStoreItemCollection.StoreSchemaVersion);

            var legacyEdmItemCollection = GetLegacyEdmItemCollection(version);

            var legacyWorkspace = new LegacyMetadata.MetadataWorkspace();
            legacyWorkspace.RegisterItemCollection(legacyEdmItemCollection);
            legacyWorkspace.RegisterItemCollection(legacyStoreItemCollection);

            var msl = string.Format(
                CultureInfo.InvariantCulture,
                MslTemplate,
                SchemaManager.GetMSLNamespaceName(version),
                legacyStoreItemCollection.GetItems<LegacyMetadata.EntityContainer>().Single().Name);

            using (var stringReader = new StringReader(msl))
            {
                using (var reader = XmlReader.Create(stringReader))
                {
                    var legacyMappingItemCollection =
                        new LegacyMapping.StorageMappingItemCollection(
                            legacyEdmItemCollection,
                            legacyStoreItemCollection,
                            new[] { reader });

                    legacyWorkspace.RegisterItemCollection(legacyMappingItemCollection);
                }
            }

            return legacyWorkspace;
        }
 internal static StorageEntityContainerMapping GetEntityContainerMap(StorageMappingItemCollection mappingCollection, EntityContainer entityContainer)
 {
     ReadOnlyCollection<StorageEntityContainerMapping> entityContainerMaps = mappingCollection.GetItems<StorageEntityContainerMapping>();
     StorageEntityContainerMapping entityContainerMap = null;
     foreach (StorageEntityContainerMapping map in entityContainerMaps)
     {
         if ((entityContainer.Equals(map.EdmEntityContainer))
             || (entityContainer.Equals(map.StorageEntityContainer)))
         {
             entityContainerMap = map;
             break;
         }
     }
     if (entityContainerMap == null)
     {
         throw new MappingException(System.Data.Entity.Strings.Mapping_NotFound_EntityContainer(entityContainer.Name));
     }
     return entityContainerMap;
 }
        private void GetViewsAndCodeDomProvider(StorageMappingItemCollection mappingCollection, out CodeDomProvider provider, out IList<EdmSchemaError> schemaErrors, out Dictionary<EntitySetBase, string> generatedViews)
        {
            //Create a CodeDomProvider based on options.
            provider = null;
            switch (m_languageOption)
            {
                case LanguageOption.GenerateCSharpCode:
                    provider = new Microsoft.CSharp.CSharpCodeProvider();
                    break;

                case LanguageOption.GenerateVBCode:
                    provider = new Microsoft.VisualBasic.VBCodeProvider();
                    break;
            }

            //Get the views for the Entity Sets and Association Sets in the mapping item collection
            GetEntitySetViews(mappingCollection, out schemaErrors, out generatedViews);
        }
        public static IList<EdmSchemaError> Validate(StorageMappingItemCollection mappingCollection, Version targetEntityFrameworkVersion)
        {
            EDesignUtil.CheckTargetEntityFrameworkVersionArgument(targetEntityFrameworkVersion, "targetEntityFrameworkVersion");
            CheckForCompatibleSchemaAndTarget(mappingCollection, targetEntityFrameworkVersion);

            // purpose of this API is to validate the mappingCollection, it basically will call GetEntitySetViews

            EDesignUtil.CheckArgumentNull(mappingCollection, "mappingCollection");

            // we need a temp var to to pass it to GetViews (since we will directly invoke GetViews)
            Dictionary<EntitySetBase, string> generatedViews;
            // mappingCollection will be validated and schemaErrors will be returned from GetViews API
            IList<EdmSchemaError> schemaErrors;

            // Validate entity set views.
            GetEntitySetViews(mappingCollection, out schemaErrors, out generatedViews);

            // Validate function imports and their mapping.
            foreach (var containerMapping in mappingCollection.GetItems<StorageEntityContainerMapping>())
            {
                foreach (var functionImport in containerMapping.EdmEntityContainer.FunctionImports)
                {
                    FunctionImportMapping functionImportMapping;
                    if (containerMapping.TryGetFunctionImportMapping(functionImport, out functionImportMapping))
                    {
                        if (functionImport.IsComposableAttribute)
                        {
                            ((FunctionImportMappingComposable)functionImportMapping).ValidateFunctionView(schemaErrors);
                        }
                    }
                    else
                    {
                        schemaErrors.Add(new EdmSchemaError(
                            Strings.UnmappedFunctionImport(functionImport.Identity),
                            (int)StorageMappingErrorCode.UnmappedFunctionImport,
                            EdmSchemaErrorSeverity.Warning));
                    }
                }
            }

            Debug.Assert(schemaErrors != null, "schemaErrors is null");
            return HandleValidationErrors(schemaErrors);
        }
        private IList<EdmSchemaError> InternalGenerateViews(
            StorageMappingItemCollection mappingCollection,
            Func<TextWriter> GetWriter,
            out TextWriter outputWriter)
        {
            IList<EdmSchemaError> schemaErrors;
            CodeDomProvider provider;
            Dictionary<EntitySetBase, string> generatedViews;
            if (GetViewsWithErrors(mappingCollection, out provider, out schemaErrors, out generatedViews))
            {
                outputWriter = null;
                return schemaErrors;
            }

            outputWriter = GetWriter();
            GenerateAndStoreViews(mappingCollection, generatedViews,
                outputWriter, provider, schemaErrors);
            
            return schemaErrors;
        }
        public IList<EdmSchemaError> GenerateViews(StorageMappingItemCollection mappingCollection, TextWriter outputWriter, Version targetEntityFrameworkVersion)
        {
            EDesignUtil.CheckArgumentNull(mappingCollection, "mappingCollection");
            EDesignUtil.CheckArgumentNull(outputWriter, "outputWriter");

            EDesignUtil.CheckTargetEntityFrameworkVersionArgument(targetEntityFrameworkVersion, "targetEntityFrameworkVersion");
            CheckForCompatibleSchemaAndTarget(mappingCollection, targetEntityFrameworkVersion);

            TextWriter writer;
            return InternalGenerateViews(mappingCollection, () => outputWriter, out writer);
        }
        private void OptimizeContextEF5(
            LanguageOption languageOption,
            string baseFileName,
            StorageMappingItemCollection mappingCollection,
            SelectedItem selectedItem)
        {
            DebugCheck.NotEmpty(baseFileName);
            DebugCheck.NotNull(mappingCollection);

            OptimizeContextCore(
                languageOption,
                baseFileName,
                selectedItem,
                viewsPath =>
                {
                    var viewGenerator = new EntityViewGenerator(languageOption);
                    var errors = viewGenerator.GenerateViews(mappingCollection, viewsPath);
                    errors.HandleErrors(Strings.Optimize_SchemaError(baseFileName));
                });
        }
        /// <summary>
        /// Creates the MetadataWorkspace for the given context type and base context type.
        /// </summary>
        /// <param name="contextType">The type of the context.</param>
        /// <param name="baseContextType">The base context type (DbContext or ObjectContext).</param>
        /// <returns>The generated <see cref="MetadataWorkspace"/></returns>
        public static MetadataWorkspace CreateMetadataWorkspaceFromResources(Type contextType, Type baseContextType)
        {
            // get the set of embedded mapping resources for the target assembly and create
            // a metadata workspace info for each group
            IEnumerable<string> metadataResourcePaths = FindMetadataResources(contextType.Assembly);
            IEnumerable<MetadataWorkspaceInfo> workspaceInfos = GetMetadataWorkspaceInfos(metadataResourcePaths);

            // Search for the correct EntityContainer by name and if found, create
            // a comlete MetadataWorkspace and return it
            foreach (var workspaceInfo in workspaceInfos)
            {
                EdmItemCollection edmItemCollection = new EdmItemCollection(workspaceInfo.Csdl);

                Type currentType = contextType;
                while (currentType != baseContextType && currentType != typeof(object))
                {
                    EntityContainer container;
                    if (edmItemCollection.TryGetEntityContainer(currentType.Name, out container))
                    {
                        StoreItemCollection store = new StoreItemCollection(workspaceInfo.Ssdl);
                        StorageMappingItemCollection mapping = new StorageMappingItemCollection(edmItemCollection, store, workspaceInfo.Msl);
                        MetadataWorkspace workspace = new MetadataWorkspace();
                        workspace.RegisterItemCollection(edmItemCollection);
                        workspace.RegisterItemCollection(store);
                        workspace.RegisterItemCollection(mapping);
                        workspace.RegisterItemCollection(new ObjectItemCollection());
                        return workspace;
                    }

                    currentType = currentType.BaseType;
                }
            }
            return null;
        }
        private static MetadataWorkspace CreateWrappedMetadataWorkspace(string metadata, IEnumerable<string> wrapperProviderNames)
        {
            MetadataWorkspace workspace = new MetadataWorkspace();

            // parse Metadata keyword and load CSDL,SSDL,MSL files into XElement structures...
            var csdl = new List<XElement>();
            var ssdl = new List<XElement>();
            var msl = new List<XElement>();
            ParseMetadata(metadata, csdl, ssdl, msl);

            // fix all SSDL files by changing 'Provider' to our provider and modifying
            foreach (var ssdlFile in ssdl)
            {
                foreach (string providerName in wrapperProviderNames)
                {
                    ssdlFile.Attribute("ProviderManifestToken").Value = ssdl[0].Attribute("Provider").Value + ";" + ssdlFile.Attribute("ProviderManifestToken").Value;
                    ssdlFile.Attribute("Provider").Value = providerName;
                }
            }

            // load item collections from XML readers created from XElements...
            EdmItemCollection eic = new EdmItemCollection(csdl.Select(c => c.CreateReader()));
            StoreItemCollection sic = new StoreItemCollection(ssdl.Select(c => c.CreateReader()));
            StorageMappingItemCollection smic = new StorageMappingItemCollection(eic, sic, msl.Select(c => c.CreateReader()));

            // and create metadata workspace based on them.
            workspace = new MetadataWorkspace();
            workspace.RegisterItemCollection(eic);
            workspace.RegisterItemCollection(sic);
            workspace.RegisterItemCollection(smic);
            return workspace;
        }
            /// <summary>
            /// Returns the update or query view for an Extent as a
            /// string.
            /// There are a series of steps that we go through for discovering a view for an extent.
            /// To start with we assume that we are working with Generated Views. To find out the 
            /// generated view we go to the ObjectItemCollection and see if it is not-null. If the ObjectItemCollection
            /// is non-null, we get the view generation assemblies that it might have cached during the
            /// Object metadata discovery.If there are no view generation assemblies we switch to the
            /// runtime view generation strategy. If there are view generation assemblies, we get the list and
            /// go through them and see if there are any assemblies that are there from which we have not already loaded
            /// the views. We collect the views from assemblies that we have not already collected from earlier.
            /// If the ObjectItemCollection is null and we are in the view generation mode, that means that
            /// the query or update is issued from the Value layer and this is the first time view has been asked for.
            /// The compile time view gen for value layer queries will work for very simple scenarios.
            /// If the users wants to get the performance benefit, they should call MetadataWorkspace.LoadFromAssembly.
            /// At this point we go through the referenced assemblies of the entry assembly( this wont work for Asp.net 
            /// or if the viewgen assembly was not referenced by the executing application).
            /// and try to see if there were any view gen assemblies. If there are, we collect the views for all extents.
            /// Once we have all the generated views gathered, we try to get the view for the extent passed in.
            /// If we find one we will return it. If we can't find one an exception will be thrown.
            /// If there were no view gen assemblies either in the ObjectItemCollection or in the list of referenced
            /// assemblies of calling assembly, we change the mode to runtime view generation and will continue to
            /// be in that mode for the rest of the lifetime of the mapping item collection.
            /// </summary>
            internal GeneratedView GetGeneratedView(EntitySetBase extent, MetadataWorkspace workspace, StorageMappingItemCollection storageMappingItemCollection)
            {
                //First check if we have collected a view from user-defined query views
                //Dont need to worry whether to generate Query view or update viw, because that is relative to the extent.
                GeneratedView view;

                if (TryGetUserDefinedQueryView(extent, out view))
                {
                    return view;
                }

                //If this is a foreign key association, manufacture a view on the fly.
                if (extent.BuiltInTypeKind == BuiltInTypeKind.AssociationSet)
                {
                    AssociationSet aSet = (AssociationSet)extent;
                    if (aSet.ElementType.IsForeignKey)
                    {
                        if (m_config.IsViewTracing)
                        {
                            Helpers.StringTraceLine(String.Empty);
                            Helpers.StringTraceLine(String.Empty);
                            Helpers.FormatTraceLine("================= Generating FK Query View for: {0} =================", aSet.Name);
                            Helpers.StringTraceLine(String.Empty);
                            Helpers.StringTraceLine(String.Empty);
                        }

                        // Although we expose a collection of constraints in the API, there is only ever one constraint.
                        Debug.Assert(aSet.ElementType.ReferentialConstraints.Count == 1, "aSet.ElementType.ReferentialConstraints.Count == 1");
                        ReferentialConstraint rc = aSet.ElementType.ReferentialConstraints.Single();

                        EntitySet dependentSet = aSet.AssociationSetEnds[rc.ToRole.Name].EntitySet;                        
                        EntitySet principalSet = aSet.AssociationSetEnds[rc.FromRole.Name].EntitySet;

                        DbExpression qView = dependentSet.Scan();

                        // Introduce an OfType view if the dependent end is a subtype of the entity set
                        EntityType dependentType = MetadataHelper.GetEntityTypeForEnd((AssociationEndMember)rc.ToRole);
                        EntityType principalType = MetadataHelper.GetEntityTypeForEnd((AssociationEndMember)rc.FromRole);
                        if (dependentSet.ElementType.IsBaseTypeOf(dependentType))
                        {
                            qView = qView.OfType(TypeUsage.Create(dependentType));
                        }

                        if (rc.FromRole.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne)
                        {
                            // Filter out instances with existing relationships.
                            qView = qView.Where(e =>
                            {
                                DbExpression filter = null;
                                foreach (EdmProperty fkProp in rc.ToProperties)
                                {
                                    DbExpression notIsNull = e.Property(fkProp).IsNull().Not();
                                    filter = null == filter ? notIsNull : filter.And(notIsNull);
                                }
                                return filter;
                            });
                        }
                        qView = qView.Select(e =>
                        {
                            List<DbExpression> ends = new List<DbExpression>();
                            foreach (AssociationEndMember end in aSet.ElementType.AssociationEndMembers)
                            {
                                if (end.Name == rc.ToRole.Name)
                                {
                                    var keyValues = new List<KeyValuePair<string, DbExpression>>();
                                    foreach (EdmMember keyMember in dependentSet.ElementType.KeyMembers)
                                    {
                                        keyValues.Add(e.Property((EdmProperty)keyMember));
                                    }
                                    ends.Add(dependentSet.RefFromKey(DbExpressionBuilder.NewRow(keyValues), dependentType));
                                }
                                else
                                {
                                    // Manufacture a key using key values.
                                    var keyValues = new List<KeyValuePair<string, DbExpression>>();
                                    foreach (EdmMember keyMember in principalSet.ElementType.KeyMembers)
                                    {
                                        int offset = rc.FromProperties.IndexOf((EdmProperty)keyMember);
                                        keyValues.Add(e.Property(rc.ToProperties[offset]));
                                    }
                                    ends.Add(principalSet.RefFromKey(DbExpressionBuilder.NewRow(keyValues), principalType));
                                }
                            }
                            return TypeUsage.Create(aSet.ElementType).New(ends);
                        });
                        return GeneratedView.CreateGeneratedViewForFKAssociationSet(aSet, aSet.ElementType, new DbQueryCommandTree(workspace, DataSpace.SSpace, qView), storageMappingItemCollection, m_config);
                    }
                }

                // If no User-defined QV is found, call memoized View Generation procedure.
                Dictionary<EntitySetBase, GeneratedView> generatedViews = m_generatedViewsMemoizer.Evaluate(extent.EntityContainer);

                if (!generatedViews.TryGetValue(extent, out view)) 
                {
                    throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.Mapping_Views_For_Extent_Not_Generated(
                        (extent.EntityContainer.DataSpace==DataSpace.SSpace)?"Table":"EntitySet",extent.Name));
                }

                return view;
            }
        private void OptimizeContextCore(LanguageOption languageOption, string baseFileName, StorageMappingItemCollection mappingCollection)
        {
            DebugCheck.NotEmpty(baseFileName);
            DebugCheck.NotNull(mappingCollection);

            var progressTimer = new Timer { Interval = 1000 };

            try
            {
                var selectedItem = _package.DTE2.SelectedItems.Item(1);
                var selectedItemPath = (string)selectedItem.ProjectItem.Properties.Item("FullPath").Value;
                var viewGenerator = new EntityViewGenerator(languageOption);
                var viewsFileName = baseFileName
                        + ".Views"
                        + ((languageOption == LanguageOption.GenerateCSharpCode)
                            ? FileExtensions.CSharp
                            : FileExtensions.VisualBasic);
                var viewsPath = Path.Combine(
                    Path.GetDirectoryName(selectedItemPath),
                    viewsFileName);

                _package.DTE2.SourceControl.CheckOutItemIfNeeded(viewsPath);

                var progress = 1;
                progressTimer.Tick += (sender, e) =>
                    {
                        _package.DTE2.StatusBar.Progress(true, string.Empty, progress, 100);
                        progress = progress == 100 ? 1 : progress + 1;
                        _package.DTE2.StatusBar.Text = Strings.Optimize_Begin(baseFileName);
                    };

                progressTimer.Start();

                Task.Factory.StartNew(
                    () =>
                    {
                        var errors = viewGenerator.GenerateViews(mappingCollection, viewsPath);
                        errors.HandleErrors(Strings.Optimize_SchemaError(baseFileName));
                    })
                    .ContinueWith(
                        t =>
                        {
                            progressTimer.Stop();
                            _package.DTE2.StatusBar.Progress(false);

                            if (t.IsFaulted)
                            {
                                _package.LogError(Strings.Optimize_Error(baseFileName), t.Exception);

                                return;
                            }

                            selectedItem.ProjectItem.ContainingProject.ProjectItems.AddFromFile(viewsPath);
                            _package.DTE2.ItemOperations.OpenFile(viewsPath);

                            _package.DTE2.StatusBar.Text = Strings.Optimize_End(baseFileName, Path.GetFileName(viewsPath));
                        },
                        TaskScheduler.FromCurrentSynchronizationContext());
            }
            catch
            {
                progressTimer.Stop();
                _package.DTE2.StatusBar.Progress(false);

                throw;
            }
        }
        public IList<EdmSchemaError> GenerateViews(StorageMappingItemCollection mappingCollection, string outputPath)
        {
            EDesignUtil.CheckArgumentNull(mappingCollection, "mappingCollection");
            EDesignUtil.CheckStringArgument(outputPath, "outputPath");

            TextWriter outputWriter = null;
            try
            {
                return InternalGenerateViews(mappingCollection, () => new StreamWriter(outputPath), out outputWriter);
            }
            finally
            {
                if (outputWriter != null)
                {
                    outputWriter.Dispose();
                }
            }
        }
        public IList<EdmSchemaError> GenerateViews(StorageMappingItemCollection mappingCollection, TextWriter outputWriter)
        {
            EDesignUtil.CheckArgumentNull(mappingCollection, "mappingCollection");

            Version targetEntityFrameworkVersion;
            IList<EdmSchemaError> errorList = GetMinimumTargetFrameworkVersion(mappingCollection, out targetEntityFrameworkVersion);

            return GenerateViews(mappingCollection, outputWriter, targetEntityFrameworkVersion).Concat(errorList).ToList();
        }
 /// <summary>
 /// Construct a new EntityContainer mapping object
 /// passing in the C-space EntityContainer  and
 /// the s-space Entity container metadata objects.
 /// </summary>
 /// <param name="entityContainer">Entity Continer type that is being mapped on the C-side</param>
 /// <param name="storageEntityContainer">Entity Continer type that is being mapped on the S-side</param>
 internal StorageEntityContainerMapping(EntityContainer entityContainer, EntityContainer storageEntityContainer, StorageMappingItemCollection storageMappingItemCollection, bool validate, bool generateUpdateViews)
 {
     this.m_entityContainer              = entityContainer;
     this.m_storageEntityContainer       = storageEntityContainer;
     this.m_storageMappingItemCollection = storageMappingItemCollection;
     this.m_memoizedCellGroupEvaluator   = new Memoizer <InputForComputingCellGroups, OutputFromComputeCellGroups>(ComputeCellGroups, new InputForComputingCellGroups());
     this.identity              = entityContainer.Identity;
     this.m_validate            = validate;
     this.m_generateUpdateViews = generateUpdateViews;
 }
        private static void CheckForCompatibleSchemaAndTarget(StorageMappingItemCollection mappingCollection, Version targetEntityFrameworkVersion)
        {
            Version mappingVersion = EntityFrameworkVersionsUtil.ConvertToVersion(mappingCollection.MappingVersion);
            if (targetEntityFrameworkVersion < mappingVersion)
            {
                throw EDesignUtil.Argument(Strings.TargetVersionSchemaVersionMismatch(targetEntityFrameworkVersion, mappingVersion), null);
            }

            Version edmVersion = EntityFrameworkVersionsUtil.ConvertToVersion(mappingCollection.EdmItemCollection.EdmVersion);
            if (targetEntityFrameworkVersion < edmVersion)
            {
                throw EDesignUtil.Argument(Strings.TargetVersionSchemaVersionMismatch(targetEntityFrameworkVersion, edmVersion), null);
            }
        }
        private static IList<EdmSchemaError> GetMinimumTargetFrameworkVersion(StorageMappingItemCollection mappingCollection, out Version targetFrameworkVersion)
        {
            List<EdmSchemaError> errorList = new List<EdmSchemaError>();

            targetFrameworkVersion = EntityFrameworkVersionsUtil.ConvertToVersion(mappingCollection.EdmItemCollection.EdmVersion);

            if (targetFrameworkVersion > EntityFrameworkVersions.Default)
            {
                errorList.Add(new EdmSchemaError(Strings.DefaultTargetVersionTooLow(EntityFrameworkVersions.Default, targetFrameworkVersion), (int)System.Data.Entity.Design.SsdlGenerator.ModelBuilderErrorCode.SchemaVersionHigherThanTargetVersion, EdmSchemaErrorSeverity.Warning));
            }

            return errorList;
        }
        public static IList<EdmSchemaError> Validate(StorageMappingItemCollection mappingCollection)
        {
            EDesignUtil.CheckArgumentNull(mappingCollection, "mappingCollection");

            Version targetEntityFrameworkVersion;
            IList<EdmSchemaError> errorList = GetMinimumTargetFrameworkVersion(mappingCollection, out targetEntityFrameworkVersion);

            return Validate(mappingCollection, targetEntityFrameworkVersion).Concat(errorList).ToList();
        }
            /// <summary>
            /// Returns the update or query view for an Extent as a
            /// string.
            /// There are a series of steps that we go through for discovering a view for an extent.
            /// To start with we assume that we are working with Generated Views. To find out the
            /// generated view we go to the ObjectItemCollection and see if it is not-null. If the ObjectItemCollection
            /// is non-null, we get the view generation assemblies that it might have cached during the
            /// Object metadata discovery.If there are no view generation assemblies we switch to the
            /// runtime view generation strategy. If there are view generation assemblies, we get the list and
            /// go through them and see if there are any assemblies that are there from which we have not already loaded
            /// the views. We collect the views from assemblies that we have not already collected from earlier.
            /// If the ObjectItemCollection is null and we are in the view generation mode, that means that
            /// the query or update is issued from the Value layer and this is the first time view has been asked for.
            /// The compile time view gen for value layer queries will work for very simple scenarios.
            /// If the users wants to get the performance benefit, they should call MetadataWorkspace.LoadFromAssembly.
            /// At this point we go through the referenced assemblies of the entry assembly( this wont work for Asp.net
            /// or if the viewgen assembly was not referenced by the executing application).
            /// and try to see if there were any view gen assemblies. If there are, we collect the views for all extents.
            /// Once we have all the generated views gathered, we try to get the view for the extent passed in.
            /// If we find one we will return it. If we can't find one an exception will be thrown.
            /// If there were no view gen assemblies either in the ObjectItemCollection or in the list of referenced
            /// assemblies of calling assembly, we change the mode to runtime view generation and will continue to
            /// be in that mode for the rest of the lifetime of the mapping item collection.
            /// </summary>
            internal GeneratedView GetGeneratedView(EntitySetBase extent, MetadataWorkspace workspace, StorageMappingItemCollection storageMappingItemCollection)
            {
                //First check if we have collected a view from user-defined query views
                //Dont need to worry whether to generate Query view or update viw, because that is relative to the extent.
                GeneratedView view;

                if (TryGetUserDefinedQueryView(extent, out view))
                {
                    return(view);
                }

                //If this is a foreign key association, manufacture a view on the fly.
                if (extent.BuiltInTypeKind == BuiltInTypeKind.AssociationSet)
                {
                    AssociationSet aSet = (AssociationSet)extent;
                    if (aSet.ElementType.IsForeignKey)
                    {
                        if (m_config.IsViewTracing)
                        {
                            Helpers.StringTraceLine(String.Empty);
                            Helpers.StringTraceLine(String.Empty);
                            Helpers.FormatTraceLine("================= Generating FK Query View for: {0} =================", aSet.Name);
                            Helpers.StringTraceLine(String.Empty);
                            Helpers.StringTraceLine(String.Empty);
                        }

                        // Although we expose a collection of constraints in the API, there is only ever one constraint.
                        Debug.Assert(aSet.ElementType.ReferentialConstraints.Count == 1, "aSet.ElementType.ReferentialConstraints.Count == 1");
                        ReferentialConstraint rc = aSet.ElementType.ReferentialConstraints.Single();

                        EntitySet dependentSet = aSet.AssociationSetEnds[rc.ToRole.Name].EntitySet;
                        EntitySet principalSet = aSet.AssociationSetEnds[rc.FromRole.Name].EntitySet;

                        DbExpression qView = dependentSet.Scan();

                        // Introduce an OfType view if the dependent end is a subtype of the entity set
                        EntityType dependentType = MetadataHelper.GetEntityTypeForEnd((AssociationEndMember)rc.ToRole);
                        EntityType principalType = MetadataHelper.GetEntityTypeForEnd((AssociationEndMember)rc.FromRole);
                        if (dependentSet.ElementType.IsBaseTypeOf(dependentType))
                        {
                            qView = qView.OfType(TypeUsage.Create(dependentType));
                        }

                        if (rc.FromRole.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne)
                        {
                            // Filter out instances with existing relationships.
                            qView = qView.Where(e =>
                            {
                                DbExpression filter = null;
                                foreach (EdmProperty fkProp in rc.ToProperties)
                                {
                                    DbExpression notIsNull = e.Property(fkProp).IsNull().Not();
                                    filter = null == filter ? notIsNull : filter.And(notIsNull);
                                }
                                return(filter);
                            });
                        }
                        qView = qView.Select(e =>
                        {
                            List <DbExpression> ends = new List <DbExpression>();
                            foreach (AssociationEndMember end in aSet.ElementType.AssociationEndMembers)
                            {
                                if (end.Name == rc.ToRole.Name)
                                {
                                    var keyValues = new List <KeyValuePair <string, DbExpression> >();
                                    foreach (EdmMember keyMember in dependentSet.ElementType.KeyMembers)
                                    {
                                        keyValues.Add(e.Property((EdmProperty)keyMember));
                                    }
                                    ends.Add(dependentSet.RefFromKey(DbExpressionBuilder.NewRow(keyValues), dependentType));
                                }
                                else
                                {
                                    // Manufacture a key using key values.
                                    var keyValues = new List <KeyValuePair <string, DbExpression> >();
                                    foreach (EdmMember keyMember in principalSet.ElementType.KeyMembers)
                                    {
                                        int offset = rc.FromProperties.IndexOf((EdmProperty)keyMember);
                                        keyValues.Add(e.Property(rc.ToProperties[offset]));
                                    }
                                    ends.Add(principalSet.RefFromKey(DbExpressionBuilder.NewRow(keyValues), principalType));
                                }
                            }
                            return(TypeUsage.Create(aSet.ElementType).New(ends));
                        });
                        return(GeneratedView.CreateGeneratedViewForFKAssociationSet(aSet, aSet.ElementType, new DbQueryCommandTree(workspace, DataSpace.SSpace, qView), storageMappingItemCollection, m_config));
                    }
                }

                // If no User-defined QV is found, call memoized View Generation procedure.
                Dictionary <EntitySetBase, GeneratedView> generatedViews = m_generatedViewsMemoizer.Evaluate(extent.EntityContainer);

                if (!generatedViews.TryGetValue(extent, out view))
                {
                    throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.Mapping_Views_For_Extent_Not_Generated(
                                                          (extent.EntityContainer.DataSpace == DataSpace.SSpace)?"Table":"EntitySet", extent.Name));
                }

                return(view);
            }
 private bool GetViewsWithErrors(StorageMappingItemCollection mappingCollection, out CodeDomProvider provider, out IList<EdmSchemaError> schemaErrors, out Dictionary<EntitySetBase, string> generatedViews)
 {
     GetViewsAndCodeDomProvider(mappingCollection, out provider, out schemaErrors, out generatedViews);
     //If the generated views are empty because of errors or warnings, then don't create an output file.
     if (generatedViews.Count == 0 && schemaErrors.Count > 0)
     {                
         return true;
     }
     return false;
 }
Esempio n. 30
0
        /// <summary>
        ///     Attempts to create a StorageMappingItemCollection from the specified metadata file, EdmItemCollection, and StoreItemCollection
        /// </summary>
        public bool TryCreateStorageMappingItemCollection(string sourcePath, EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection, out StorageMappingItemCollection storageMappingItemCollection)
        {
            storageMappingItemCollection = null;

            if(String.IsNullOrEmpty(sourcePath))
                throw new ArgumentException("sourcePath");

            if(edmItemCollection == null)
                throw new ArgumentNullException("edmItemCollection");

            if(storeItemCollection == null)
                throw new ArgumentNullException("storeItemCollection");

            ItemCollection itemCollection = null;
            var collectionBuilder = new StorageMappingItemCollectionBuilder(_textTransformation, edmItemCollection, storeItemCollection);
            if(collectionBuilder.TryCreateItemCollection(_textTransformation.Host.ResolvePath(sourcePath), out itemCollection))
                storageMappingItemCollection = (StorageMappingItemCollection) itemCollection;
            return storageMappingItemCollection != null;
        }
 private static void GetEntitySetViews(StorageMappingItemCollection mappingCollection,
     out IList<EdmSchemaError> schemaErrors, out Dictionary<EntitySetBase, string> generatedViews)
 {
     generatedViews = mappingCollection.GenerateEntitySetViews(out schemaErrors);
 }
        private static MetadataWorkspace GetProviderSchemaMetadataWorkspace(DbProviderServices providerServices, DbConnection providerConnection, Version targetEntityFrameworkVersion)
        {
            XmlReader csdl = null;
            XmlReader ssdl = null;
            XmlReader msl = null;

            Debug.Assert(EntityFrameworkVersions.IsValidVersion(targetEntityFrameworkVersion), "EntityFrameworkVersions.IsValidVersion(targetEntityFrameworkVersion)");
            string csdlName;
            string ssdlName;
            string mslName;
            if (targetEntityFrameworkVersion >= EntityFrameworkVersions.Version3)
            {
                csdlName = DbProviderManifest.ConceptualSchemaDefinitionVersion3;
                ssdlName = DbProviderManifest.StoreSchemaDefinitionVersion3;
                mslName = DbProviderManifest.StoreSchemaMappingVersion3;
            }
            else
            {
                csdlName = DbProviderManifest.ConceptualSchemaDefinition;
                ssdlName = DbProviderManifest.StoreSchemaDefinition;
                mslName = DbProviderManifest.StoreSchemaMapping;
            }

            try
            {
                // create the metadata workspace
                MetadataWorkspace workspace = new MetadataWorkspace();

                string manifestToken = providerServices.GetProviderManifestToken(providerConnection);
                DbProviderManifest providerManifest = providerServices.GetProviderManifest(manifestToken);

                // create the EdmItemCollection
                IList<EdmSchemaError> errors;
                ssdl = providerManifest.GetInformation(ssdlName);
                string location = Strings.DbProviderServicesInformationLocationPath(providerConnection.GetType().Name, ssdlName);
                List<string> ssdlLocations = new List<string>(1);
                ssdlLocations.Add(location);
                StoreItemCollection storeItemCollection = new StoreItemCollection(new XmlReader[] { ssdl }, ssdlLocations.AsReadOnly(), out errors);
                ThrowOnError(errors);
                workspace.RegisterItemCollection(storeItemCollection);

                csdl = DbProviderServices.GetConceptualSchemaDefinition(csdlName);
                location = Strings.DbProviderServicesInformationLocationPath(typeof(DbProviderServices).Name, csdlName);
                List<string> csdlLocations = new List<string>(1);
                csdlLocations.Add(location);
                EdmItemCollection edmItemCollection = new EdmItemCollection(new XmlReader[] { csdl }, csdlLocations.AsReadOnly(), out errors);
                ThrowOnError(errors);
                workspace.RegisterItemCollection(edmItemCollection);

                msl = providerManifest.GetInformation(mslName);
                location = Strings.DbProviderServicesInformationLocationPath(providerConnection.GetType().Name, DbProviderManifest.StoreSchemaMapping);
                List<string> mslLocations = new List<string>(1);
                mslLocations.Add(location);
                StorageMappingItemCollection mappingItemCollection = new StorageMappingItemCollection(edmItemCollection,
                                                                         storeItemCollection,
                                                                         new XmlReader[] { msl },
                                                                         mslLocations,
                                                                         out errors);
                ThrowOnError(errors);
                workspace.RegisterItemCollection(mappingItemCollection);

                // make the views generate here so we can wrap the provider schema problems
                // in a ProviderIncompatibleException
                ForceViewGeneration(workspace);
                return workspace;
            }
            catch (ProviderIncompatibleException)
            {
                // we don't really want to catch this one, just rethrow it
                throw;
            }
            catch (Exception e)
            {
                if (MetadataUtil.IsCatchableExceptionType(e))
                {
                    throw EDesignUtil.ProviderIncompatible(Strings.ProviderSchemaErrors, e);
                }

                throw;
            }
            finally
            {
                if (csdl != null) ((IDisposable)csdl).Dispose();
                if (ssdl != null) ((IDisposable)ssdl).Dispose();
                if (msl != null) ((IDisposable)msl).Dispose();
            }
        }
        /// <summary>
        /// Generates the code to store the views in a C# or a VB file based on the
        /// options passed in by the user.
        /// </summary>
        /// <param name="mappingCollection"></param>
        /// <param name="generatedViews"></param>
        /// <param name="sourceWriter"></param>
        /// <param name="provider"></param>
        /// <returns></returns>
        private static void GenerateAndStoreViews(StorageMappingItemCollection mappingCollection,
            Dictionary<EntitySetBase, string> generatedViews, TextWriter sourceWriter, CodeDomProvider provider, IList<EdmSchemaError> schemaErrors)
        {
            EdmItemCollection edmCollection = mappingCollection.EdmItemCollection;
            StoreItemCollection storeCollection = mappingCollection.StoreItemCollection;

            //Create an emtpty compile unit and build up the generated code
            CodeCompileUnit compileUnit = new CodeCompileUnit();

            //Add the namespace for generated code
            CodeNamespace codeNamespace = new CodeNamespace(EntityViewGenerationConstants.NamespaceName);
            //Add copyright notice to the namespace comment.
            compileUnit.Namespaces.Add(codeNamespace);

            foreach (var storageEntityContainerMapping in mappingCollection.GetItems<StorageEntityContainerMapping>())
            {
                //Throw warning when containerMapping contains query view for bug 547285.
                if (HasQueryView(storageEntityContainerMapping))
                {
                    schemaErrors.Add(new EdmSchemaError(
                        Strings.UnsupportedQueryViewInEntityContainerMapping(storageEntityContainerMapping.Identity), 
                        (int)StorageMappingErrorCode.UnsupportedQueryViewInEntityContainerMapping, 
                        EdmSchemaErrorSeverity.Warning));
                    continue;
                }

                #region Class Declaration

                string edmContainerName = storageEntityContainerMapping.EdmEntityContainer.Name;
                string storeContainerName = storageEntityContainerMapping.StorageEntityContainer.Name;

                string hashOverMappingClosure = MetadataMappingHasherVisitor.GetMappingClosureHash(edmCollection.EdmVersion, storageEntityContainerMapping);

                StringBuilder inputForTypeNameContent = new StringBuilder(hashOverMappingClosure);

                string viewStorageTypeName = EntityViewGenerationConstants.ViewGenerationTypeNamePrefix + StringHashBuilder.ComputeHash(MetadataHelper.CreateMetadataHashAlgorithm(edmCollection.EdmVersion),  inputForTypeNameContent.ToString()).ToUpperInvariant();

                //Add typeof expression to get the type that contains ViewGen type. This will help us in avoiding to go through 
                //all the types in the assembly. I have also verified that this works with VB with a root namespace prepended to the
                //namespace since VB is picking up the type correctly as long as it is in the same assembly even with out the root namespace.
                CodeTypeOfExpression viewGenTypeOfExpression = new CodeTypeOfExpression(EntityViewGenerationConstants.NamespaceName + "." + viewStorageTypeName);
                //Add the assembly attribute that marks the assembly as the one that contains the generated views
                CodeAttributeDeclaration viewGenAttribute = new CodeAttributeDeclaration(EntityViewGenerationConstants.ViewGenerationCustomAttributeName);
                CodeAttributeArgument viewGenTypeArgument = new CodeAttributeArgument(viewGenTypeOfExpression);
                viewGenAttribute.Arguments.Add(viewGenTypeArgument);
                compileUnit.AssemblyCustomAttributes.Add(viewGenAttribute);

                //Add the type which will be the class that contains all the views in this assembly
                CodeTypeDeclaration viewStoringType = CreateTypeForStoringViews(viewStorageTypeName);

                //Add the constructor, this will be the only method that this type will contain
                //Create empty constructor.
                CodeConstructor viewStoringTypeConstructor = CreateConstructorForViewStoringType();
                viewStoringType.Attributes = MemberAttributes.Public;


                //Get an expression that expresses this instance
                CodeThisReferenceExpression thisRef = new CodeThisReferenceExpression();


                string viewHash = MetadataHelper.GenerateHashForAllExtentViewsContent(edmCollection.EdmVersion, GenerateDictionaryForEntitySetNameAndView(generatedViews));


                CodeAssignStatement EdmEntityContainerNameStatement = 
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.EdmEntityContainerName), 
                        new CodePrimitiveExpression(edmContainerName));
                CodeAssignStatement StoreEntityContainerNameStatement =
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.StoreEntityContainerName),
                        new CodePrimitiveExpression(storeContainerName));
                CodeAssignStatement HashOverMappingClosureStatement =
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.HashOverMappingClosure),
                        new CodePrimitiveExpression(hashOverMappingClosure));
                CodeAssignStatement HashOverAllExtentViewsStatement =
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.HashOverAllExtentViews),
                        new CodePrimitiveExpression(viewHash));
                CodeAssignStatement ViewCountStatement =
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.ViewCountPropertyName),
                        new CodePrimitiveExpression(generatedViews.Count));

                viewStoringTypeConstructor.Statements.Add(EdmEntityContainerNameStatement);
                viewStoringTypeConstructor.Statements.Add(StoreEntityContainerNameStatement);
                viewStoringTypeConstructor.Statements.Add(HashOverMappingClosureStatement);
                viewStoringTypeConstructor.Statements.Add(HashOverAllExtentViewsStatement);
                viewStoringTypeConstructor.Statements.Add(ViewCountStatement);

                //Add the constructor to the type
                viewStoringType.Members.Add(viewStoringTypeConstructor);
                //Add the method to store views to the type
                CreateAndAddGetViewAtMethod(viewStoringType, generatedViews);

                //Add the type to the namespace
                codeNamespace.Types.Add(viewStoringType);

                #endregion
            }

            if (codeNamespace.Types.Count > 0)
            {
                GenerateCode(sourceWriter, provider, compileUnit);
                sourceWriter.Flush();
            }
        }
        /// <summary>
        /// Attempts to create a StorageMappingItemCollection from the specified metadata file, EdmItemCollection, and StoreItemCollection
        /// </summary>
        public bool TryCreateStorageMappingItemCollection(string sourcePath, EdmItemCollection edmItemCollection, StoreItemCollection storeItemCollection, out StorageMappingItemCollection storageMappingItemCollection)
        {
            storageMappingItemCollection = null;

            if (!ValidateInputPath(sourcePath, _textTransformation))
            {
                return false;
            }

            if (edmItemCollection == null)
            {
                throw new ArgumentNullException("edmItemCollection");
            }

            if (storeItemCollection == null)
            {
                throw new ArgumentNullException("storeItemCollection");
            }

            ItemCollection itemCollection = null;
            StorageMappingItemCollectionBuilder collectionBuilder = new StorageMappingItemCollectionBuilder(_textTransformation, edmItemCollection, storeItemCollection);
            if (collectionBuilder.TryCreateItemCollection(_textTransformation.Host.ResolvePath(sourcePath), out itemCollection))
            {
                storageMappingItemCollection = (StorageMappingItemCollection)itemCollection;
            }
            return storageMappingItemCollection != null;
        }