Пример #1
0
        /// <summary>
        /// Creates generated view object for the combination of the <paramref name="setMapping"/>.Set and the <paramref name="type"/>.
        /// This constructor is used for user-defined query views only.
        /// </summary>
        internal static bool TryParseUserSpecifiedView(StorageSetMapping setMapping,
                                                       EntityTypeBase type,
                                                       string eSQL,
                                                       bool includeSubtypes,
                                                       StorageMappingItemCollection mappingItemCollection,
                                                       ConfigViewGenerator config,
                                                       /*out*/ IList <EdmSchemaError> errors,
                                                       out GeneratedView generatedView)
        {
            bool failed = false;

            DbQueryCommandTree commandTree;
            DiscriminatorMap   discriminatorMap;
            Exception          parserException;

            if (!GeneratedView.TryParseView(eSQL, true, setMapping.Set, mappingItemCollection, config, out commandTree, out discriminatorMap, out parserException))
            {
                EdmSchemaError error = new EdmSchemaError(System.Data.Entity.Strings.Mapping_Invalid_QueryView2(setMapping.Set.Name, parserException.Message),
                                                          (int)StorageMappingErrorCode.InvalidQueryView, EdmSchemaErrorSeverity.Error,
                                                          setMapping.EntityContainerMapping.SourceLocation, setMapping.StartLineNumber, setMapping.StartLinePosition, parserException);
                errors.Add(error);
                failed = true;
            }
            else
            {
                Debug.Assert(commandTree != null, "commandTree not set after parsing the view");

                // Verify that all expressions appearing in the view are supported.
                foreach (var error in ViewValidator.ValidateQueryView(commandTree, setMapping, type, includeSubtypes))
                {
                    errors.Add(error);
                    failed = true;
                }

                // Verify that the result type of the query view is assignable to the element type of the entityset
                CollectionType queryResultType = (commandTree.Query.ResultType.EdmType) as CollectionType;
                if ((queryResultType == null) || (!setMapping.Set.ElementType.IsAssignableFrom(queryResultType.TypeUsage.EdmType)))
                {
                    EdmSchemaError error = new EdmSchemaError(System.Data.Entity.Strings.Mapping_Invalid_QueryView_Type(setMapping.Set.Name),
                                                              (int)StorageMappingErrorCode.InvalidQueryViewResultType, EdmSchemaErrorSeverity.Error,
                                                              setMapping.EntityContainerMapping.SourceLocation, setMapping.StartLineNumber, setMapping.StartLinePosition);
                    errors.Add(error);
                    failed = true;
                }
            }

            if (!failed)
            {
                generatedView = new GeneratedView(setMapping.Set, type, commandTree, eSQL, discriminatorMap, mappingItemCollection, config);
                return(true);
            }
            else
            {
                generatedView = null;
                return(false);
            }
        }
        private QueryRewriter GenerateViewsForExtentAndType(EdmType generatedType, ViewgenContext context, CqlIdentifiers identifiers, ViewSet views, ViewGenMode mode)
        {
            Debug.Assert(mode != ViewGenMode.GenerateAllViews, "By definition this method can not handle generating views for all extents");

            QueryRewriter queryRewriter = new QueryRewriter(generatedType, context, mode);

            queryRewriter.GenerateViewComponents();

            // Get the basic view
            CellTreeNode basicView = queryRewriter.BasicView;

            if (m_config.IsNormalTracing)
            {
                Helpers.StringTrace("Basic View: ");
                Helpers.StringTraceLine(basicView.ToString());
            }

            CellTreeNode simplifiedView = GenerateSimplifiedView(basicView, queryRewriter.UsedCells);

            if (m_config.IsNormalTracing)
            {
                Helpers.StringTraceLine(String.Empty);
                Helpers.StringTrace("Simplified View: ");
                Helpers.StringTraceLine(simplifiedView.ToString());
            }

            CqlGenerator cqlGen = new CqlGenerator(simplifiedView,
                                                   queryRewriter.CaseStatements,
                                                   identifiers,
                                                   context.MemberMaps.ProjectedSlotMap,
                                                   queryRewriter.UsedCells.Count,
                                                   queryRewriter.TopLevelWhereClause,
                                                   m_entityContainerMapping.StorageMappingItemCollection);

            string             eSQLView;
            DbQueryCommandTree commandTree;

            if (m_config.GenerateEsql)
            {
                eSQLView    = cqlGen.GenerateEsql();
                commandTree = null;
            }
            else
            {
                eSQLView    = null;
                commandTree = cqlGen.GenerateCqt();
            }

            GeneratedView generatedView = GeneratedView.CreateGeneratedView(context.Extent, generatedType, commandTree, eSQLView, m_entityContainerMapping.StorageMappingItemCollection, m_config);

            views.Add(context.Extent, generatedView);

            return(queryRewriter);
        }
Пример #3
0
        /// <summary>
        /// Creates generated view object for the combination of the <paramref name="setMapping"/>.Set and the <paramref name="type"/>. 
        /// This constructor is used for user-defined query views only.
        /// </summary>
        internal static bool TryParseUserSpecifiedView(StorageSetMapping setMapping,
                                                       EntityTypeBase type,
                                                       string eSQL,
                                                       bool includeSubtypes,
                                                       StorageMappingItemCollection mappingItemCollection,
                                                       ConfigViewGenerator config,
                                                       /*out*/ IList<EdmSchemaError> errors,
                                                       out GeneratedView generatedView)
        {
            bool failed = false;

            DbQueryCommandTree commandTree;
            DiscriminatorMap discriminatorMap;
            Exception parserException;
            if (!GeneratedView.TryParseView(eSQL, true, setMapping.Set, mappingItemCollection, config, out commandTree, out discriminatorMap, out parserException))
            {
                EdmSchemaError error = new EdmSchemaError(System.Data.Entity.Strings.Mapping_Invalid_QueryView2(setMapping.Set.Name, parserException.Message),
                                           (int)StorageMappingErrorCode.InvalidQueryView, EdmSchemaErrorSeverity.Error,
                                           setMapping.EntityContainerMapping.SourceLocation, setMapping.StartLineNumber, setMapping.StartLinePosition, parserException);
                errors.Add(error);
                failed = true;
            }
            else
            {
                Debug.Assert(commandTree != null, "commandTree not set after parsing the view");

                // Verify that all expressions appearing in the view are supported.
                foreach (var error in ViewValidator.ValidateQueryView(commandTree, setMapping, type, includeSubtypes))
                {
                    errors.Add(error);
                    failed = true;
                }

                // Verify that the result type of the query view is assignable to the element type of the entityset
                CollectionType queryResultType = (commandTree.Query.ResultType.EdmType) as CollectionType;
                if ((queryResultType == null) || (!setMapping.Set.ElementType.IsAssignableFrom(queryResultType.TypeUsage.EdmType)))
                {
                    EdmSchemaError error = new EdmSchemaError(System.Data.Entity.Strings.Mapping_Invalid_QueryView_Type(setMapping.Set.Name),
                                               (int)StorageMappingErrorCode.InvalidQueryViewResultType, EdmSchemaErrorSeverity.Error,
                                               setMapping.EntityContainerMapping.SourceLocation, setMapping.StartLineNumber, setMapping.StartLinePosition);
                    errors.Add(error);
                    failed = true;
                }
            }

            if (!failed)
            {
                generatedView = new GeneratedView(setMapping.Set, type, commandTree, eSQL, discriminatorMap, mappingItemCollection, config);
                return true;
            }
            else
            {
                generatedView = null;
                return false;
            }
        }
 /// <summary>
 /// Tries to generate the Oftype or OfTypeOnly query view for a given entity set and type. 
 /// Returns false if the view could not be generated.
 /// Possible reasons for failing are 
 ///   1) Passing in OfTypeOnly on an abstract type
 ///   2) In user-specified query views mode a query for the given type is absent
 /// </summary>
 internal bool TryGetGeneratedViewOfType(MetadataWorkspace workspace, EntitySetBase entity, EntityTypeBase type, bool includeSubtypes, out GeneratedView generatedView)
 {
     OfTypeQVCacheKey key = new OfTypeQVCacheKey(entity, new Pair<EntityTypeBase, bool>(type, includeSubtypes));
     generatedView = this.m_generatedViewOfTypeMemoizer.Evaluate(key);
     return (generatedView != null);
 }
            /// <summary>
            /// Generates a single query view for a given Extent and type. It is used to generate OfType and OfTypeOnly views.
            /// </summary>
            /// <param name="includeSubtypes">Whether the view should include extents that are subtypes of the given entity</param>
            private bool TryGenerateQueryViewOfType(EntityContainer entityContainer, EntitySetBase entity, EntityTypeBase type, bool includeSubtypes, out GeneratedView generatedView)
            {
                Debug.Assert(entityContainer != null);
                Debug.Assert(entity != null);
                Debug.Assert(type != null);

                if (type.Abstract)
                {
                    generatedView = null;
                    return false;
                }

                //Get the mapping that has the entity container mapped.
                StorageEntityContainerMapping entityContainerMap = MappingMetadataHelper.GetEntityContainerMap(m_storageMappingItemCollection, entityContainer);
                Debug.Assert(!entityContainerMap.IsEmpty, "There are no entity set maps");

                bool success;
                ViewGenResults viewGenResults = ViewgenGatekeeper.GenerateTypeSpecificQueryView(entityContainerMap, m_config, entity, type, includeSubtypes, out success);
                if (!success)
                {
                    generatedView = null;
                    return false; //could not generate view
                }

                KeyToListMap<EntitySetBase, GeneratedView> extentMappingViews = viewGenResults.Views;

                if (viewGenResults.HasErrors)
                {
                    throw new MappingException(Helper.CombineErrorMessage(viewGenResults.Errors));
                }

                Debug.Assert(extentMappingViews.AllValues.Count() == 1, "Viewgen should have produced only one view");
                generatedView = extentMappingViews.AllValues.First();

                return true;
            }
 /// <summary>
 /// this method will be called in metadatworkspace, the signature is the same as the one in ViewDictionary
 /// </summary>
 /// <param name="workspace"></param>
 /// <param name="entity"></param>
 /// <param name="type"></param>
 /// <param name="includeSubtypes"></param>
 /// <param name="generatedView"></param>
 /// <returns></returns>
 internal bool TryGetGeneratedViewOfType(MetadataWorkspace workspace, EntitySetBase entity, EntityTypeBase type, bool includeSubtypes, out GeneratedView generatedView)
 {
     return this.m_viewDictionary.TryGetGeneratedViewOfType(workspace, entity, type, includeSubtypes, out generatedView);
 }
 /// <summary>
 /// Tries to generate the Oftype or OfTypeOnly query view for a given entity set and type. 
 /// Returns false if the view could not be generated.
 /// Possible reasons for failing are 
 ///   1) Passing in OfTypeOnly on an abstract type
 ///   2) In user-specified query views mode a query for the given type is absent
 /// </summary>
 internal bool TryGetGeneratedViewOfType(
     EntitySetBase entity, EntityTypeBase type, bool includeSubtypes, out GeneratedView generatedView)
 {
     var key = new OfTypeQVCacheKey(entity, new Pair<EntityTypeBase, bool>(type, includeSubtypes));
     generatedView = m_generatedViewOfTypeMemoizer.Evaluate(key);
     return (generatedView != null);
 }
 /// <summary>
 /// this method will be called in metadatworkspace, the signature is the same as the one in ViewDictionary
 /// </summary>
 /// <param name="entity"></param>
 /// <param name="type"></param>
 /// <param name="includeSubtypes"></param>
 /// <param name="generatedView"></param>
 /// <returns></returns>
 internal bool TryGetGeneratedViewOfType(
     EntitySetBase entity, EntityTypeBase type, bool includeSubtypes, out GeneratedView generatedView)
 {
     return m_viewDictionary.TryGetGeneratedViewOfType(entity, type, includeSubtypes, out generatedView);
 }