/// <summary> /// Handle discriminator maps (determine which can safely be used in the query) /// </summary> private void ProcessDiscriminatorMaps(Dictionary <md.EntitySetBase, DiscriminatorMapInfo> discriminatorMaps) { // Only use custom type discrimination where a type has a single entity set. Where // there are multiple sets, discriminator properties and flattened representations // may be incompatible. Dictionary <md.EntitySetBase, ExplicitDiscriminatorMap> filteredMaps = null; if (null != discriminatorMaps) { filteredMaps = new Dictionary <md.EntitySetBase, ExplicitDiscriminatorMap>(discriminatorMaps.Count, discriminatorMaps.Comparer); foreach (KeyValuePair <md.EntitySetBase, DiscriminatorMapInfo> setMapPair in discriminatorMaps) { md.EntitySetBase set = setMapPair.Key; ExplicitDiscriminatorMap map = setMapPair.Value.DiscriminatorMap; if (null != map) { md.EntityTypeBase rootType = GetRootType(set.ElementType); bool hasOneSet = GetEntitySet(rootType) != null; if (hasOneSet) { filteredMaps.Add(set, map); } } } if (filteredMaps.Count == 0) { // don't bother keeping the dictionary if it's empty filteredMaps = null; } } m_discriminatorMaps = filteredMaps; }
/// <summary> /// Creates a "flattened" table definition. /// /// The table has one column for each specified property in the "properties" parameter. /// The name and datatype of each table column are taken from the corresponding property. /// /// The keys of the table (if any) are those specified in the "keyProperties" parameter /// /// The table may correspond to an entity set (if the entityset parameter was non-null) /// </summary> /// <param name="properties">prperties corresponding to columns of the table</param> /// <param name="keyProperties"></param> /// <param name="extent">entityset corresponding to the table (if any)</param> internal TableMD(IEnumerable<EdmProperty> properties, IEnumerable<EdmMember> keyProperties, EntitySetBase extent) : this(extent) { Dictionary<string, ColumnMD> columnMap = new Dictionary<string, ColumnMD>(); m_flattened = true; foreach (EdmProperty p in properties) { ColumnMD newColumn = new ColumnMD(this, p); m_columns.Add(newColumn); columnMap[p.Name] = newColumn; } foreach (EdmMember p in keyProperties) { ColumnMD keyColumn; if (!columnMap.TryGetValue(p.Name, out keyColumn)) { Debug.Assert(false, "keyMember not in columns?"); } else { m_keys.Add(keyColumn); } } }
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> /// Creates generated view object for the combination of the <paramref name="extent"/> and the <paramref name="type"/>. /// This constructor is used for regular cell-based view generation. /// </summary> internal static GeneratedView CreateGeneratedView(EntitySetBase extent, EdmType type, DbQueryCommandTree commandTree, string eSQL, StorageMappingItemCollection mappingItemCollection, ConfigViewGenerator config) { // If config.GenerateEsql is specified, eSQL must be non-null. // If config.GenerateEsql is false, commandTree is non-null except the case when loading pre-compiled eSQL views. Debug.Assert(!config.GenerateEsql || !String.IsNullOrEmpty(eSQL), "eSQL must be specified"); DiscriminatorMap discriminatorMap = null; if (commandTree != null) { commandTree = ViewSimplifier.SimplifyView(extent, commandTree); // See if the view matches the "discriminated" pattern (allows simplification of generated store commands) if (extent.BuiltInTypeKind == BuiltInTypeKind.EntitySet) { if (DiscriminatorMap.TryCreateDiscriminatorMap((EntitySet)extent, commandTree.Query, out discriminatorMap)) { Debug.Assert(discriminatorMap != null, "discriminatorMap == null after it has been created"); } } } return new GeneratedView(extent, type, commandTree, eSQL, discriminatorMap, mappingItemCollection, config); }
/// <summary> /// Recursively generates <see cref="MemberPath"/>s for the members of the types stored in the <paramref name="extent"/>. /// </summary> internal static MemberProjectionIndex Create(EntitySetBase extent, EdmItemCollection edmItemCollection) { // We generate the indices for the projected slots as we traverse the metadata. MemberProjectionIndex index = new MemberProjectionIndex(); GatherPartialSignature(index, edmItemCollection, new MemberPath(extent), false); // need not only keys return index; }
// ObjectStateEntry will not be detached and creation will be handled from ObjectStateManager internal ObjectStateEntry(ObjectStateManager cache, EntitySet entitySet, EntityState state) { Debug.Assert(cache != null, "cache cannot be null."); _cache = cache; _entitySet = entitySet; _state = state; }
// ObjectStateEntry will not be detached and creation will be handled from ObjectStateManager internal ObjectStateEntry(ObjectStateManager cache, EntitySet entitySet, EntityState state) { //Contract.Requires(cache != null); _cache = cache; _entitySet = entitySet; _state = state; }
/// <summary> /// Creates generated view object for the combination of the <paramref name="extent"/> and the <paramref name="type"/>. /// This constructor is used for FK association sets only. /// </summary> internal static GeneratedView CreateGeneratedViewForFKAssociationSet(EntitySetBase extent, EdmType type, DbQueryCommandTree commandTree, StorageMappingItemCollection mappingItemCollection, ConfigViewGenerator config) { return new GeneratedView(extent, type, commandTree, null, null, mappingItemCollection, config); }
public RelationshipChange(EntityKey sourceKey, EntityKey targetKey, object source, object target, EntitySetBase entitySet, EntityState state) { _sourceKey = sourceKey; _targetKey = targetKey; _source = source; _target = target; _entitySet = entitySet; _state = state; }
/// <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; } } }
/// <summary> /// Is there a parent child relationship between table1 and table2 ? /// </summary> /// <param name="table1">parent table ?</param> /// <param name="table2">child table ?</param> /// <param name="constraints">list of constraints ?</param> /// <returns>true if there is at least one constraint</returns> internal bool IsParentChildRelationship(md.EntitySetBase table1, md.EntitySetBase table2, out List <ForeignKeyConstraint> constraints) { LoadRelationships(table1.EntityContainer); LoadRelationships(table2.EntityContainer); ExtentPair extentPair = new ExtentPair(table1, table2); return(m_parentChildRelationships.TryGetValue(extentPair, out constraints)); }
/// <summary> /// Creates an cql block representing the <paramref name="extent"/> (the FROM part). /// SELECT is given by <paramref name="slots"/>, WHERE by <paramref name="whereClause"/> and AS by <paramref name="blockAliasNum"/>. /// </summary> internal ExtentCqlBlock(EntitySetBase extent, CellQuery.SelectDistinct selectDistinct, SlotInfo[] slots, BoolExpression whereClause, CqlIdentifiers identifiers, int blockAliasNum) : base(slots, EmptyChildren, whereClause, identifiers, blockAliasNum) { m_extent = extent; m_nodeTableAlias = identifiers.GetBlockAlias(); m_selectDistinct = selectDistinct; }
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; } } }
protected virtual void Visit(EntitySetBase entitySetBase) { // this is a switching node, so no object header and footer will be add for this node, // also this Visit won't add the object to the seen list switch (entitySetBase.BuiltInTypeKind) { case BuiltInTypeKind.EntitySet: Visit((EntitySet)entitySetBase); break; case BuiltInTypeKind.AssociationSet: Visit((AssociationSet)entitySetBase); break; default: Debug.Fail(string.Format(CultureInfo.InvariantCulture, "Found type '{0}', did we add a new type?", entitySetBase.BuiltInTypeKind)); break; } }
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; } } } }
virtual internal void Reset() { _cache = null; _entitySet = null; _state = EntityState.Detached; }
internal static bool IsEntitySet(EntitySetBase entitySetBase) { return(BuiltInTypeKind.EntitySet == entitySetBase.BuiltInTypeKind); }
/// <summary> /// Given an extent and its corresponding view, invokes the parser to check if the view definition is syntactically correct. /// Iff parsing succeeds: <paramref name="commandTree"/> and <paramref name="discriminatorMap"/> are set to the parse result and method returns true, /// otherwise if parser has thrown a catchable exception, it is returned via <paramref name="parserException"/> parameter, /// otherwise exception is re-thrown. /// </summary> private static bool TryParseView(string eSQL, bool isUserSpecified, EntitySetBase extent, StorageMappingItemCollection mappingItemCollection, ConfigViewGenerator config, out DbQueryCommandTree commandTree, out DiscriminatorMap discriminatorMap, out Exception parserException) { commandTree = null; discriminatorMap = null; parserException = null; // We do not catch any internal exceptions any more config.StartSingleWatch(PerfType.ViewParsing); try { // If it is a user specified view, allow all queries. Otherwise parse the view in the restricted mode. ParserOptions.CompilationMode compilationMode = ParserOptions.CompilationMode.RestrictedViewGenerationMode; if (isUserSpecified) { compilationMode = ParserOptions.CompilationMode.UserViewGenerationMode; } Debug.Assert(!String.IsNullOrEmpty(eSQL), "eSQL query is not specified"); commandTree = (DbQueryCommandTree)ExternalCalls.CompileView(eSQL, mappingItemCollection, compilationMode); // For non user-specified views, perform simplification. if (!isUserSpecified) { commandTree = ViewSimplifier.SimplifyView(extent, commandTree); } // See if the view matches the "discriminated" pattern (allows simplification of generated store commands) if (extent.BuiltInTypeKind == BuiltInTypeKind.EntitySet) { if (DiscriminatorMap.TryCreateDiscriminatorMap((EntitySet)extent, commandTree.Query, out discriminatorMap)) { Debug.Assert(discriminatorMap != null, "discriminatorMap == null after it has been created"); } } } catch (Exception e) { // Catching all the exception types since Query parser seems to be throwing veriety of // exceptions - EntityException, ArgumentException, ArgumentNullException etc. if (EntityUtil.IsCatchableExceptionType(e)) { parserException = e; } else { throw; } } finally { config.StopSingleWatch(PerfType.ViewParsing); } Debug.Assert(commandTree != null || parserException != null, "Either commandTree or parserException is expected."); // Note: m_commandTree might have been initialized by a previous call to this method, so in consequent calls it might occur that // both m_commandTree and parserException are not null - this would mean that the last parse attempt failed, but m_commandTree value is // preserved from the previous call. return parserException == null; }
private GeneratedView(EntitySetBase extent, EdmType type, DbQueryCommandTree commandTree, string eSQL, DiscriminatorMap discriminatorMap, StorageMappingItemCollection mappingItemCollection, ConfigViewGenerator config) { // At least one of the commandTree or eSQL must be specified. // Both are specified in the case of user-defined views. Debug.Assert(commandTree != null || !String.IsNullOrEmpty(eSQL), "commandTree or eSQL must be specified"); m_extent = extent; m_type = type; m_commandTree = commandTree; m_eSQL = eSQL; m_discriminatorMap = discriminatorMap; m_mappingItemCollection = mappingItemCollection; m_config = config; if (m_config.IsViewTracing) { StringBuilder trace = new StringBuilder(1024); this.ToCompactString(trace); Helpers.FormatTraceLine("CQL view for {0}", trace.ToString()); } }
internal IEnumerable<MemberPath> NonConditionMembers(EntitySetBase extent) { foreach (MemberPath path in m_nonConditionDomainMap.Keys) { if (path.Extent.Equals(extent)) { yield return path; } } }
internal ExtentPair(md.EntitySetBase left, md.EntitySetBase right) { m_left = left; m_right = right; }
/// <summary> /// Create a typed-table definition corresponding to an entityset (if specified) /// /// The table has exactly one column - the type of the column is specified by /// the "type" parameter. This table is considered to be un-"flattened" /// </summary> /// <param name="type">type of each element (row) of the table</param> /// <param name="extent">entityset corresponding to the table (if any)</param> internal TableMD(TypeUsage type, EntitySetBase extent) : this(extent) { m_columns.Add(new ColumnMD(this, "element", type)); m_flattened = !PlanCompiler.TypeUtils.IsStructuredType(type); }
private static string GetExtentFullName(EntitySetBase entitySet) { //We store the full Extent Name in the generated code which is //EntityContainer name + "." + entitysetName return entitySet.EntityContainer.Name + EntityViewGenerationConstants.QualificationCharacter + entitySet.Name; }
internal static DbQueryCommandTree SimplifyView(EntitySetBase extent, DbQueryCommandTree view) { ViewSimplifier vs = new ViewSimplifier(view.MetadataWorkspace, extent); view = vs.Simplify(view); return view; }
/// <summary> /// Returns the extent in the target space, for the given entity container. /// </summary> /// <param name="entityContainer">name of the entity container in target space</param> /// <param name="extentName">name of the extent</param> /// <param name="ignoreCase">Whether to do case-sensitive member look up or not</param> /// <param name="outSet">extent in target space, if a match is found</param> /// <returns>returns true, if a match is found otherwise returns false</returns> internal bool TryGetExtent(EntityContainer entityContainer, String extentName, bool ignoreCase, out EntitySetBase outSet) { // There are no entity containers in the OSpace. So there is no mapping involved. // Hence the name should be a valid name in the CSpace. return entityContainer.BaseEntitySets.TryGetValue(extentName, ignoreCase, out outSet); }
private Node BuildRelPropertyExpression( EntitySetBase entitySet, RelProperty relProperty, Node keyExpr) { // // Make a copy of the current key expression // keyExpr = OpCopier.Copy(m_command, keyExpr); // // Find the relationship set corresponding to this entityset (and relProperty) // Return a null ref, if we can't find one // var relSet = FindRelationshipSet(entitySet, relProperty); if (relSet == null) { return m_command.CreateNode(m_command.CreateNullOp(relProperty.ToEnd.TypeUsage)); } var scanTableOp = m_command.CreateScanTableOp(Command.CreateTableDefinition(relSet)); PlanCompiler.Assert( scanTableOp.Table.Columns.Count == 1, "Unexpected column count for table:" + scanTableOp.Table.TableMetadata.Extent + "=" + scanTableOp.Table.Columns.Count); var scanTableVar = scanTableOp.Table.Columns[0]; var scanNode = m_command.CreateNode(scanTableOp); var sourceEndNode = m_command.CreateNode( m_command.CreatePropertyOp(relProperty.FromEnd), m_command.CreateNode(m_command.CreateVarRefOp(scanTableVar))); var predicateNode = m_command.BuildComparison( OpType.EQ, keyExpr, m_command.CreateNode(m_command.CreateGetRefKeyOp(keyExpr.Op.Type), sourceEndNode)); var filterNode = m_command.CreateNode( m_command.CreateFilterOp(), scanNode, predicateNode); // // Process the node, and then add this as a subquery to the parent relop // var ret = VisitNode(filterNode); ret = AddSubqueryToParentRelOp(scanTableVar, ret); // // Now extract out the target end property // ret = m_command.CreateNode( m_command.CreatePropertyOp(relProperty.ToEnd), ret); return ret; }
/// <summary> /// Find the relationshipset that matches the current entityset + from/to roles /// </summary> /// <param name="entitySet"></param> /// <param name="relProperty"></param> /// <returns></returns> private static RelationshipSet FindRelationshipSet(EntitySetBase entitySet, RelProperty relProperty) { foreach (var es in entitySet.EntityContainer.BaseEntitySets) { var rs = es as AssociationSet; if (rs != null && rs.ElementType.EdmEquals(relProperty.Relationship) && rs.AssociationSetEnds[relProperty.FromEnd.Identity].EntitySet.EdmEquals(entitySet)) { return rs; } } return null; }
private static List<LeftCellWrapper> GetWrappersFromContext(ViewgenContext context, EntitySetBase extent) { List<LeftCellWrapper> wrappers; if (context == null) { wrappers = new List<LeftCellWrapper>(); } else { Debug.Assert(context.Extent.Equals(extent), "ViewgenContext extent and expected extent different"); wrappers = context.AllWrappersForExtent; } return wrappers; }
/// <summary> /// Returns the extent in the target space, for the given entity container. /// </summary> /// <param name="entityContainer">name of the entity container in target space</param> /// <param name="extentName">name of the extent</param> /// <param name="ignoreCase">Whether to do case-sensitive member look up or not</param> /// <param name="outSet">extent in target space, if a match is found</param> /// <returns>returns true, if a match is found otherwise returns false</returns> internal bool TryGetExtent(EntityContainer entityContainer, String extentName, bool ignoreCase, out EntitySetBase outSet) { // There are no entity containers in the OSpace. So there is no mapping involved. // Hence the name should be a valid name in the CSpace. return(entityContainer.BaseEntitySets.TryGetValue(extentName, ignoreCase, out outSet)); }
private ViewSimplifier(MetadataWorkspace mws, EntitySetBase viewTarget) { this.metadata = mws; this.extent = viewTarget; }
/// <summary> /// Build up a node tree that represents the set of instances from the given table that are at least /// of the specified type ("ofType"). If "ofType" is NULL, then all rows are returned /// /// Return the outputVar from the nodetree /// </summary> /// <param name="entitySet">the entityset or relationshipset to scan over</param> /// <param name="ofType">the element types we're interested in</param> /// <param name="resultVar">the output var produced by this node tree</param> /// <returns>the node tree</returns> private Node BuildOfTypeTable(EntitySetBase entitySet, TypeUsage ofType, out Var resultVar) { var tableMetadata = Command.CreateTableDefinition(entitySet); var tableOp = m_command.CreateScanTableOp(tableMetadata); var tableNode = m_command.CreateNode(tableOp); var tableVar = tableOp.Table.Columns[0]; Node resultNode; // // Build a logical "oftype" expression - simply a filter predicate // if ((ofType != null) && !entitySet.ElementType.EdmEquals(ofType.EdmType)) { m_command.BuildOfTypeTree(tableNode, tableVar, ofType, true, out resultNode, out resultVar); } else { resultNode = tableNode; resultVar = tableVar; } return resultNode; }
/// <summary> /// Given an entity constructor (NewEntityOp, DiscriminatedNewEntityOp), build up /// the list of rel-property expressions. /// /// Walks through the list of relevant rel-properties, and builds up expressions /// (using BuildRelPropertyExpression) for each rel-property that does not have /// an expression already built (preBuiltExpressions) /// </summary> /// <param name="entitySet">entity set that holds instances of the entity we're building</param> /// <param name="relPropertyList">the list of relevant rel-properties for this entity type</param> /// <param name="prebuiltExpressions">the prebuilt rel-property expressions</param> /// <param name="keyExpr">the key of the entity instance</param> /// <returns>a list of rel-property expressions (lines up 1-1 with 'relPropertyList')</returns> private IEnumerable<Node> BuildAllRelPropertyExpressions( EntitySetBase entitySet, List<RelProperty> relPropertyList, Dictionary<RelProperty, Node> prebuiltExpressions, Node keyExpr) { foreach (var r in relPropertyList) { Node relPropNode; if (!prebuiltExpressions.TryGetValue(r, out relPropNode)) { relPropNode = BuildRelPropertyExpression(entitySet, r, keyExpr); } yield return relPropNode; } }
/// <summary> /// private initializer /// </summary> /// <param name="extent">the entity set corresponding to this table (if any)</param> private TableMD(EntitySetBase extent) { m_columns = new List<ColumnMD>(); m_keys = new List<ColumnMD>(); m_extent = extent; }
/// <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); } }
internal void AddEntitySetBase(EntitySetBase entitySetBase) { _baseEntitySets.Source.Add(entitySetBase); }