internal StorageModificationFunctionMapping( EntitySetBase entitySet, EntityTypeBase entityType, EdmFunction function, IEnumerable<StorageModificationFunctionParameterBinding> parameterBindings, FunctionParameter rowsAffectedParameter, IEnumerable<StorageModificationFunctionResultBinding> resultBindings) { //Contract.Requires(entitySet != null); //Contract.Requires(function != null); //Contract.Requires(parameterBindings != null); Function = function; RowsAffectedParameter = rowsAffectedParameter; ParameterBindings = parameterBindings.ToList().AsReadOnly(); if (null != resultBindings) { var bindings = resultBindings.ToList(); if (0 < bindings.Count) { ResultBindings = bindings.AsReadOnly(); } } CollocatedAssociationSetEnds = GetReferencedAssociationSetEnds(entitySet as EntitySet, entityType as EntityType, parameterBindings) .ToList() .AsReadOnly(); }
/// <summary> /// Merge the discriminatorMap info we just found with what we've already found. /// /// In practice, if either the current or the new map is from an OfTypeOnly view, we /// have to avoid the optimizations. /// /// If we have a new map that is a superset of the current map, then we can just swap /// the new map for the current one. /// /// If the current map is tha super set of the new one ther's nothing to do. /// /// (Of course, if neither has changed, then we really don't need to look) /// </summary> internal void Merge(EntityTypeBase neededRootEntityType, bool includesSubtypes, ExplicitDiscriminatorMap discriminatorMap) { // If what we've found doesn't exactly match what we are looking for we have more work to do if (RootEntityType != neededRootEntityType || IncludesSubTypes != includesSubtypes) { if (!IncludesSubTypes || !includesSubtypes) { // If either the original or the new map is from an of-type-only view we can't // merge, we just have to not optimize this case. DiscriminatorMap = null; } if (TypeSemantics.IsSubTypeOf(RootEntityType, neededRootEntityType)) { // we're asking for a super type of existing type, and what we had is a proper // subset of it -we can replace the existing item. RootEntityType = neededRootEntityType; DiscriminatorMap = discriminatorMap; } if (!TypeSemantics.IsSubTypeOf(neededRootEntityType, RootEntityType)) { // If either the original or the new map is from an of-type-only view we can't // merge, we just have to not optimize this case. DiscriminatorMap = null; } } }
/// <summary> /// Constructs the name of the collection type /// </summary> /// <param name="entityTypeBase">The entity type base that this ref type refers to</param> /// <returns>The identity of the resulting ref type</returns> private static string GetIdentity(EntityTypeBase entityTypeBase) { StringBuilder builder = new StringBuilder(50); builder.Append("reference["); entityTypeBase.BuildIdentity(builder); builder.Append("]"); return builder.ToString(); }
/// <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> /// 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> /// 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; } } }
private void CreateAndAddNavigationProperty(StructuralType cspaceType, StructuralType ospaceType, NavigationProperty cspaceProperty, PropertyInfo clrProperty) { EdmType ospaceRelationship; if (SessionData.CspaceToOspace.TryGetValue(cspaceProperty.RelationshipType, out ospaceRelationship)) { Debug.Assert(ospaceRelationship is StructuralType, "Structural type expected."); bool foundTarget = false; EdmType targetType = null; if (Helper.IsCollectionType(cspaceProperty.TypeUsage.EdmType)) { EdmType findType; foundTarget = SessionData.CspaceToOspace.TryGetValue((StructuralType)((CollectionType)cspaceProperty.TypeUsage.EdmType).TypeUsage.EdmType, out findType); if (foundTarget) { Debug.Assert(findType is StructuralType, "Structural type expected."); targetType = findType.GetCollectionType(); } } else { EdmType findType; foundTarget = SessionData.CspaceToOspace.TryGetValue((StructuralType)cspaceProperty.TypeUsage.EdmType, out findType); if (foundTarget) { Debug.Assert(findType is StructuralType, "Structural type expected."); targetType = findType; } } Debug.Assert(foundTarget, "Since the relationship will only be created if it can find the types for both ends, we will never fail to find one of the ends"); NavigationProperty navigationProperty = new NavigationProperty(cspaceProperty.Name, TypeUsage.Create(targetType), clrProperty); navigationProperty.RelationshipType = (RelationshipType)ospaceRelationship; // we can use First because o-space relationships are created directly from // c-space relationship navigationProperty.ToEndMember = (RelationshipEndMember)((RelationshipType)ospaceRelationship).Members.First(e => e.Name == cspaceProperty.ToEndMember.Name); navigationProperty.FromEndMember = (RelationshipEndMember)((RelationshipType)ospaceRelationship).Members.First(e => e.Name == cspaceProperty.FromEndMember.Name); ospaceType.AddMember(navigationProperty); } else { EntityTypeBase missingType = cspaceProperty.RelationshipType.RelationshipEndMembers.Select(e => ((RefType)e.TypeUsage.EdmType).ElementType).First(e => e != cspaceType); string message = SessionData.LoadMessageLogger.CreateErrorMessageWithTypeSpecificLoadLogs( Strings.Validator_OSpace_Convention_RelationshipNotLoaded(cspaceProperty.RelationshipType.FullName, missingType.FullName), missingType); SessionData.EdmItemErrors.Add(new EdmItemError(message, ospaceType)); } }
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; } } }
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; } } } }
//---------------------------------------------------------------------------------------------- // Possible Future Enhancement: revisit factoring of EntitySetBase and delta between C constructs and S constructs // // Currently, we need to have a way to map an entityset or a relationship set in S space // to the appropriate structures in the store. In order to address this we said we would // add new ItemAttributes (tableName, schemaName and catalogName to the EntitySetBase)... // problem with this is that we are bleading a leaf-level, store specific set of constructs // into the object model for things that may exist at either C or S. // // We need to do this for now to push forward on enabling the conversion but we need to re-examine // whether we should have separate C and S space constructs or some other mechanism for // maintaining this metadata. //---------------------------------------------------------------------------------------------- #region Constructors /// <summary> /// The constructor for constructing the EntitySet with a given name and an entity type /// </summary> /// <param name="name">The name of the EntitySet</param> /// <param name="schema">The db schema</param> /// <param name="table">The db table</param> /// <param name="definingQuery">The provider specific query that should be used to retrieve the EntitySet</param> /// <param name="entityType">The entity type of the entities that this entity set type contains</param> /// <exception cref="System.ArgumentNullException">Thrown if the name or entityType argument is null</exception> internal EntitySetBase(string name, string schema, string table, string definingQuery, EntityTypeBase entityType) { EntityUtil.GenericCheckArgumentNull(entityType, "entityType"); EntityUtil.CheckStringArgument(name, "name"); // SQLBU 480236: catalogName, schemaName & tableName are allowed to be null, empty & non-empty _name = name; //---- name of the 'schema' //---- this is used by the SQL Gen utility to support generation of the correct name in the store _schema = schema; //---- name of the 'table' //---- this is used by the SQL Gen utility to support generation of the correct name in the store _table = table; //---- the Provider specific query to use to retrieve the EntitySet data _definingQuery = definingQuery; this.ElementType = entityType; }
/// <summary> /// Get the rel properties declared by this type (and *not* by any of its subtypes) /// </summary> /// <param name="entityType">the entity type</param> /// <returns>set of rel properties declared for this type</returns> internal IEnumerable<RelProperty> GetDeclaredOnlyRelProperties(EntityTypeBase entityType) { List<RelProperty> relProperties; if (_relPropertyMap.TryGetValue(entityType, out relProperties)) { foreach (RelProperty p in relProperties) { yield return p; } } yield break; }
/// <summary> /// Return members for MetdataWorkspace.GetRequiredOriginalValueMembers() and MetdataWorkspace.GetRelevantMembersForUpdate() methods. /// </summary> /// <param name="entitySet">An EntitySet belonging to the C-Space. Must not be null.</param> /// <param name="entityType">An EntityType that participates in the given EntitySet. Must not be null.</param> /// <param name="interestingMembersKind">Scenario the members should be returned for.</param> /// <returns>ReadOnlyCollection of interesting members for the requested scenario (<paramref name="interestingMembersKind"/>).</returns> internal ReadOnlyCollection<EdmMember> GetInterestingMembers(EntitySetBase entitySet, EntityTypeBase entityType, InterestingMembersKind interestingMembersKind) { Debug.Assert(entitySet != null, "entitySet != null"); Debug.Assert(entityType != null, "entityType != null"); var key = new Tuple<EntitySetBase, EntityTypeBase, InterestingMembersKind>(entitySet, entityType, interestingMembersKind); return _cachedInterestingMembers.GetOrAdd(key, FindInterestingMembers(entitySet, entityType, interestingMembersKind)); }
internal static bool EntityTypeEquals(EntityTypeBase entityType1, EntityTypeBase entityType2) { return object.ReferenceEquals(entityType1, entityType2); }
private ErrorLog GenerateQueryViewForExtentAndType( CqlIdentifiers identifiers, ViewSet views, EntitySetBase entity, EntityTypeBase type, ViewGenMode mode) { Debug.Assert(mode != ViewGenMode.GenerateAllViews); // Keep track of the mapping exceptions that we have generated var errorLog = new ErrorLog(); if (m_config.IsViewTracing) { Helpers.StringTraceLine(String.Empty); Helpers.StringTraceLine(String.Empty); Helpers.FormatTraceLine( "================= Generating {0} Query View for: {1} ===========================", (mode == ViewGenMode.OfTypeViews) ? "OfType" : "OfTypeOnly", entity.Name); Helpers.StringTraceLine(String.Empty); Helpers.StringTraceLine(String.Empty); } try { // (1) view generation (checks that extents are fully mapped) var context = CreateViewgenContext(entity, ViewTarget.QueryView, identifiers); var queryRewriter = GenerateViewsForExtentAndType(type, context, identifiers, views, mode); } catch (InternalMappingException exception) { // All exceptions have mapping errors in them Debug.Assert(exception.ErrorLog.Count > 0, "Incorrectly created mapping exception"); errorLog.Merge(exception.ErrorLog); } return errorLog; }
/// <summary> /// Entry point for Type specific generation of Query Views /// </summary> internal static ViewGenResults GenerateTypeSpecificQueryView(StorageEntityContainerMapping containerMapping, ConfigViewGenerator config, EntitySetBase entity, EntityTypeBase type, bool includeSubtypes, out bool success) { EntityUtil.CheckArgumentNull(containerMapping, "containerMapping"); EntityUtil.CheckArgumentNull(config, "config"); EntityUtil.CheckArgumentNull(entity, "entity"); EntityUtil.CheckArgumentNull(type, "type"); Debug.Assert(!type.Abstract, "Can not generate OfType/OfTypeOnly query view for and abstract type"); if (config.IsNormalTracing) { Helpers.StringTraceLine(""); Helpers.StringTraceLine("<<<<<<<< Generating Query View for Entity [" + entity.Name + "] OfType" + (includeSubtypes ? "" : "Only") + "(" + type.Name + ") >>>>>>>"); } if (containerMapping.GetEntitySetMapping(entity.Name).QueryView != null) { //Type-specific QV does not exist in the cache, but // there is a EntitySet QV. So we can't generate the view (no mapping exists for this EntitySet) // and we rely on Query to call us again to get the EntitySet View. success = false; return null; } //Compute Cell Groups or get it from Memoizer InputForComputingCellGroups args = new InputForComputingCellGroups(containerMapping, config); OutputFromComputeCellGroups result = containerMapping.GetCellgroups(args); success = result.Success; if (!success) { return null; } List<ForeignConstraint> foreignKeyConstraints = result.ForeignKeyConstraints; // Get a Clone of cell groups from cache since cells are modified during viewgen, and we dont want the cached copy to change List<CellGroup> cellGroups = cellGroups = result.CellGroups.Select(setOfcells => new CellGroup(setOfcells.Select(cell => new Cell(cell)))).ToList(); List<Cell> cells = result.Cells; CqlIdentifiers identifiers = result.Identifiers; ViewGenResults viewGenResults = new ViewGenResults(); ErrorLog tmpLog = EnsureAllCSpaceContainerSetsAreMapped(cells, config, containerMapping); if (tmpLog.Count > 0) { viewGenResults.AddErrors(tmpLog); Helpers.StringTraceLine(viewGenResults.ErrorsToString()); success = true; //atleast we tried successfully return viewGenResults; } foreach (CellGroup cellGroup in cellGroups) { if (!DoesCellGroupContainEntitySet(cellGroup, entity)) { continue; } ViewGenerator viewGenerator = null; ErrorLog groupErrorLog = new ErrorLog(); try { viewGenerator = new ViewGenerator(cellGroup, config, foreignKeyConstraints, containerMapping); } catch (InternalMappingException exception) { // All exceptions have mapping errors in them Debug.Assert(exception.ErrorLog.Count > 0, "Incorrectly created mapping exception"); groupErrorLog = exception.ErrorLog; } if (groupErrorLog.Count > 0) { break; } Debug.Assert(viewGenerator != null); //make sure there is no exception thrown that does not add error to log ViewGenMode mode = includeSubtypes ? ViewGenMode.OfTypeViews : ViewGenMode.OfTypeOnlyViews; groupErrorLog = viewGenerator.GenerateQueryViewForSingleExtent(viewGenResults.Views, identifiers, entity, type, mode); if (groupErrorLog.Count != 0) { viewGenResults.AddErrors(groupErrorLog); } } success = true; return viewGenResults; }
internal StorageModificationFunctionMapping( EntitySetBase entitySet, EntityTypeBase entityType, EdmFunction function, IEnumerable<StorageModificationFunctionParameterBinding> parameterBindings, FunctionParameter rowsAffectedParameter, IEnumerable<StorageModificationFunctionResultBinding> resultBindings) { EntityUtil.CheckArgumentNull(entitySet, "entitySet"); this.Function = EntityUtil.CheckArgumentNull(function, "function"); this.RowsAffectedParameter = rowsAffectedParameter; this.ParameterBindings = EntityUtil.CheckArgumentNull(parameterBindings, "parameterBindings") .ToList().AsReadOnly(); if (null != resultBindings) { List<StorageModificationFunctionResultBinding> bindings = resultBindings.ToList(); if (0 < bindings.Count) { ResultBindings = bindings.AsReadOnly(); } } this.CollocatedAssociationSetEnds = GetReferencedAssociationSetEnds(entitySet as EntitySet, entityType as EntityType, parameterBindings) .ToList() .AsReadOnly(); }
internal ErrorLog GenerateQueryViewForSingleExtent( ViewSet views, CqlIdentifiers identifiers, EntitySetBase entity, EntityTypeBase type, ViewGenMode mode) { Debug.Assert(mode != ViewGenMode.GenerateAllViews); if (m_config.IsNormalTracing) { var builder = new StringBuilder(); Cell.CellsToBuilder(builder, m_cellGroup); Helpers.StringTraceLine(builder.ToString()); } // Check if the cellgroup is consistent and all known S constraints are // satisified by the known C constraints var validator = new CellGroupValidator(m_cellGroup, m_config); var errorLog = validator.Validate(); if (errorLog.Count > 0) { errorLog.PrintTrace(); return errorLog; } // Make sure that the foreign key constraints are not violated if (m_config.IsValidationEnabled) { CheckForeignKeyConstraints(errorLog); } if (errorLog.Count > 0) { errorLog.PrintTrace(); return errorLog; // If we have discovered errors here, do not generate query views } // For the S-side, we add NOT ... for each scalar constant so // that if we have C, P in the mapping but the store has C, P, S, // we can handle it in the query views m_updateDomainMap.ExpandDomainsToIncludeAllPossibleValues(); foreach (var cell in m_cellGroup) { cell.SQuery.WhereClause.FixDomainMap(m_updateDomainMap); } errorLog = GenerateQueryViewForExtentAndType(identifiers, views, entity, type, mode); return errorLog; }
/// <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> /// Finds foreign key properties and adds them to the <paramref name="interestingMembers"/>. /// </summary> /// <param name="entitySetBase">Entity set <paramref name="entityType"/> relates to. Must not be null.</param> /// <param name="entityType">Entity type for which to find foreign key properties. Must not be null.</param> /// <param name="interestingMembers">The list the interesting members (if any) will be added to. Must not be null.</param> private void FindForeignKeyProperties(EntitySetBase entitySetBase, EntityTypeBase entityType, List<EdmMember> interestingMembers) { var entitySet = entitySetBase as EntitySet; if (entitySet != null && entitySet.HasForeignKeyRelationships) { // (6) Foreign keys // select all foreign key properties defined on the entityType and all its ancestors interestingMembers.AddRange( MetadataHelper.GetTypeAndParentTypesOf(entityType, this.m_edmCollection, true) .SelectMany(e => ((EntityType)e).Properties) .Where(p => entitySet.ForeignKeyDependents.SelectMany(fk => fk.Item2.ToProperties).Contains(p))); } }
/// <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); }
internal DiscriminatorMapInfo(EntityTypeBase rootEntityType, bool includesSubTypes, ExplicitDiscriminatorMap discriminatorMap) { RootEntityType = rootEntityType; IncludesSubTypes = includesSubTypes; DiscriminatorMap = discriminatorMap; }
/// <summary> /// If the discrminator map we're already tracking for this type (in this entityset) /// isn't already rooted at our required type, then we have to suppress the use of /// the descriminator maps when we constrct the structuredtypes; see SQLBUDT #615744 /// </summary> private void DetermineDiscriminatorMapUsage( Node viewNode, EntitySetBase entitySet, EntityTypeBase rootEntityType, bool includeSubtypes) { ExplicitDiscriminatorMap discriminatorMap = null; // we expect the view to be capped with a project; we're just being careful here. if (viewNode.Op.OpType == OpType.Project) { var discriminatedNewEntityOp = viewNode.Child1.Child0.Child0.Op as DiscriminatedNewEntityOp; if (null != discriminatedNewEntityOp) { discriminatorMap = discriminatedNewEntityOp.DiscriminatorMap; } } DiscriminatorMapInfo discriminatorMapInfo; if (!m_discriminatorMaps.TryGetValue(entitySet, out discriminatorMapInfo)) { if (null == rootEntityType) { rootEntityType = entitySet.ElementType; includeSubtypes = true; } discriminatorMapInfo = new DiscriminatorMapInfo(rootEntityType, includeSubtypes, discriminatorMap); m_discriminatorMaps.Add(entitySet, discriminatorMapInfo); } else { discriminatorMapInfo.Merge(rootEntityType, includeSubtypes, discriminatorMap); } }
/// <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; }
protected virtual void Visit(EntityTypeBase entityTypeBase) { // switching node if (entityTypeBase == null) { return; } switch (entityTypeBase.BuiltInTypeKind) { case BuiltInTypeKind.AssociationType: Visit((AssociationType)entityTypeBase); break; case BuiltInTypeKind.EntityType: Visit((EntityType)entityTypeBase); break; default: Debug.Fail(String.Format(CultureInfo.InvariantCulture, "Found type '{0}', did we add a new type?", entityTypeBase.BuiltInTypeKind)); break; } }
/// <summary> /// Get the rel-properties of this entity and its supertypes (starting from the root) /// </summary> /// <param name="entityType">the entity type</param> /// <returns>set of rel-properties for this entity type (and its supertypes)</returns> internal IEnumerable<RelProperty> GetRelProperties(EntityTypeBase entityType) { if (entityType.BaseType != null) { foreach (RelProperty p in GetRelProperties(entityType.BaseType as EntityTypeBase)) { yield return p; } } foreach (RelProperty p in GetDeclaredOnlyRelProperties(entityType)) { yield return p; } }
/// <summary> /// Finds interesting members for MetdataWorkspace.GetRequiredOriginalValueMembers() and MetdataWorkspace.GetRelevantMembersForUpdate() methods /// for the given <paramref name="entitySet"/> and <paramref name="entityType"/>. /// </summary> /// <param name="entitySet">An EntitySet belonging to the C-Space. Must not be null.</param> /// <param name="entityType">An EntityType that participates in the given EntitySet. Must not be null.</param> /// <param name="interestingMembersKind">Scenario the members should be returned for.</param> /// <returns>ReadOnlyCollection of interesting members for the requested scenario (<paramref name="interestingMembersKind"/>).</returns> private ReadOnlyCollection<EdmMember> FindInterestingMembers(EntitySetBase entitySet, EntityTypeBase entityType, InterestingMembersKind interestingMembersKind) { Debug.Assert(entitySet != null, "entitySet != null"); Debug.Assert(entityType != null, "entityType != null"); var interestingMembers = new List<EdmMember>(); foreach (var storageTypeMapping in MappingMetadataHelper.GetMappingsForEntitySetAndSuperTypes(this, entitySet.EntityContainer, entitySet, entityType)) { StorageAssociationTypeMapping associationTypeMapping = storageTypeMapping as StorageAssociationTypeMapping; if (associationTypeMapping != null) { FindInterestingAssociationMappingMembers(associationTypeMapping, interestingMembers); } else { Debug.Assert(storageTypeMapping is StorageEntityTypeMapping, "StorageEntityTypeMapping expected."); FindInterestingEntityMappingMembers((StorageEntityTypeMapping)storageTypeMapping, interestingMembersKind, interestingMembers); } } // For backwards compatibility we don't return foreign keys from the obsolete MetadataWorkspace.GetRequiredOriginalValueMembers() method if (interestingMembersKind != InterestingMembersKind.RequiredOriginalValueMembers) { FindForeignKeyProperties(entitySet, entityType, interestingMembers); } foreach (var functionMappings in MappingMetadataHelper .GetModificationFunctionMappingsForEntitySetAndType(this, entitySet.EntityContainer, entitySet, entityType) .Where(functionMappings => functionMappings.UpdateFunctionMapping != null)) { FindInterestingFunctionMappingMembers(functionMappings, interestingMembersKind, ref interestingMembers); } Debug.Assert(interestingMembers != null, "interestingMembers must never be null."); return new ReadOnlyCollection<EdmMember>(interestingMembers.Distinct().ToList()); }
protected override void Visit(EntityTypeBase entityTypeBase) { base.Visit(entityTypeBase); }
/// <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); }
private static EdmProperty[] GetProperties(EntityTypeBase entityType, IList<Som.PropertyRefElement> properties) { Debug.Assert(properties.Count != 0); EdmProperty[] result = new EdmProperty[properties.Count]; for (int i = 0; i < properties.Count; i++) { result[i] = (EdmProperty)entityType.Members[properties[i].Name]; } return result; }
/// <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); }