internal ForeignKeyConstraint(md.RelationshipType relType, md.RelationshipSet relationshipSet, md.ReferentialConstraint constraint) { md.AssociationSet assocSet = relationshipSet as md.AssociationSet; md.AssociationEndMember fromEnd = constraint.FromRole as md.AssociationEndMember; md.AssociationEndMember toEnd = constraint.ToRole as md.AssociationEndMember; // Currently only Associations are supported if (null == assocSet || null == fromEnd || null == toEnd) { throw EntityUtil.NotSupported(); } m_constraint = constraint; md.EntitySet parent = System.Data.Common.Utils.MetadataHelper.GetEntitySetAtEnd(assocSet, fromEnd); // relationshipSet.GetRelationshipEndExtent(constraint.FromRole); md.EntitySet child = System.Data.Common.Utils.MetadataHelper.GetEntitySetAtEnd(assocSet, toEnd); // relationshipSet.GetRelationshipEndExtent(constraint.ToRole); m_extentPair = new ExtentPair(parent, child); m_childKeys = new List <string>(); foreach (md.EdmProperty prop in constraint.ToProperties) { m_childKeys.Add(prop.Name); } m_parentKeys = new List <string>(); foreach (md.EdmProperty prop in constraint.FromProperties) { m_parentKeys.Add(prop.Name); } PlanCompiler.Assert((md.RelationshipMultiplicity.ZeroOrOne == fromEnd.RelationshipMultiplicity || md.RelationshipMultiplicity.One == fromEnd.RelationshipMultiplicity), "from-end of relationship constraint cannot have multiplicity greater than 1"); }
/// <summary> /// Initialize Metadata for an AssociationSet /// </summary> internal AssociationSetMetadata(Set<EntitySet> affectedTables, AssociationSet associationSet, MetadataWorkspace workspace) { // If there is only 1 table, there can be no ambiguity about the "destination" of a relationship, so such // sets are not typically required. var isRequired = 1 < affectedTables.Count; // determine the ends of the relationship var ends = associationSet.AssociationSetEnds; // find collocated entities foreach (var table in affectedTables) { // Find extents influencing the table var influencingExtents = MetadataHelper.GetInfluencingEntitySetsForTable(table, workspace); foreach (var influencingExtent in influencingExtents) { foreach (var end in ends) { // If the extent is an end of the relationship and we haven't already added it to the // required set... if (end.EntitySet.EdmEquals(influencingExtent)) { if (isRequired) { AddEnd(ref RequiredEnds, end.CorrespondingAssociationEndMember); } else if (null == RequiredEnds || !RequiredEnds.Contains(end.CorrespondingAssociationEndMember)) { AddEnd(ref OptionalEnds, end.CorrespondingAssociationEndMember); } } } } } // fix Required and Optional sets FixSet(ref RequiredEnds); FixSet(ref OptionalEnds); // for associations with referential constraints, the principal end is always interesting // since its key values may take precedence over the key values of the dependent end foreach (var constraint in associationSet.ElementType.ReferentialConstraints) { // FromRole is the principal end in the referential constraint var principalEnd = (AssociationEndMember)constraint.FromRole; if (!RequiredEnds.Contains(principalEnd) && !OptionalEnds.Contains(principalEnd)) { AddEnd(ref IncludedValueEnds, principalEnd); } } FixSet(ref IncludedValueEnds); }
protected virtual void Visit(AssociationSet associationSet) { Visit(associationSet.ElementType); Visit(associationSet.EntityContainer); foreach (var end in associationSet.AssociationSetEnds) { Visit(end); } }
internal StorageAssociationSetModificationFunctionMapping( AssociationSet associationSet, StorageModificationFunctionMapping deleteFunctionMapping, StorageModificationFunctionMapping insertFunctionMapping) { this.AssociationSet = EntityUtil.CheckArgumentNull(associationSet, "associationSet"); this.DeleteFunctionMapping = deleteFunctionMapping; this.InsertFunctionMapping = insertFunctionMapping; }
internal StorageAssociationSetModificationFunctionMapping( AssociationSet associationSet, StorageModificationFunctionMapping deleteFunctionMapping, StorageModificationFunctionMapping insertFunctionMapping) { //Contract.Requires(associationSet != null); AssociationSet = associationSet; DeleteFunctionMapping = deleteFunctionMapping; InsertFunctionMapping = insertFunctionMapping; }
private void GetFromAssociationSetEnd(AssociationSet definingSet, AssociationSet multiplicitySet, out AssociationSetEnd associationSetEnd, out RelationshipMultiplicity multiplicity, out OperationAction deleteBehavior) { // for a situation like this (CD is CascadeDelete) // // -------- CD -------- CD -------- // | A |1 <- 1| AtoB |* <- 1| B | // | |-------| |-------| | // | | | | | | // -------- -------- -------- // // You get // -------- CD -------- // | A |* <- 1| B | // | |-------| | // | | | | // -------- -------- // // Notice that the of the new "link table association" muliplicities are opposite of what comming into the original link table // this seems counter intuitive at first, but makes sense when you think all the way through it // // CascadeDelete Behavior (we can assume the runtime will always delete cascade // to the link table from the outside tables (it actually doesn't, but that is a associationSetEnd = GetAssociationSetEnd(definingSet, true); AssociationSetEnd multiplicityAssociationSetEnd = GetAssociationSetEnd(multiplicitySet, false); multiplicity = multiplicityAssociationSetEnd.CorrespondingAssociationEndMember.RelationshipMultiplicity; deleteBehavior = OperationAction.None; if (multiplicity != RelationshipMultiplicity.Many) { OperationAction otherEndBehavior = GetAssociationSetEnd(definingSet, false).CorrespondingAssociationEndMember.DeleteBehavior; if(otherEndBehavior == OperationAction.None) { // Since the other end does not have an operation // that means that only one end could possibly have an operation, that is good // so set it the operation deleteBehavior = multiplicityAssociationSetEnd.CorrespondingAssociationEndMember.DeleteBehavior; } } }
internal StorageModificationFunctionMemberPath(IEnumerable<EdmMember> members, AssociationSet associationSetNavigation) { //Contract.Requires(members != null); Members = new ReadOnlyCollection<EdmMember>(new List<EdmMember>(members)); if (null != associationSetNavigation) { Debug.Assert(2 == Members.Count, "Association bindings must always consist of the end and the key"); // find the association set end AssociationSetEnd = associationSetNavigation.AssociationSetEnds[Members[1].Name]; } }
internal WithRelationship(AssociationSet associationSet, AssociationEndMember fromEnd, EntityType fromEndEntityType, AssociationEndMember toEnd, EntityType toEndEntityType, IEnumerable<MemberPath> toEndEntityKeyMemberPaths) { m_associationSet = associationSet; m_fromEnd = fromEnd; m_fromEndEntityType = fromEndEntityType; m_toEnd = toEnd; m_toEndEntityType = toEndEntityType; m_toEndEntitySet = MetadataHelper.GetEntitySetAtEnd(associationSet, toEnd); m_toEndEntityKeyMemberPaths = toEndEntityKeyMemberPaths; }
// effects: Creates a foreign key constraint of the form: // <i_childTable, i_childColumns> --> <i_parentTable, i_childColumns> // i_fkeySet is the name of the constraint internal ForeignConstraint(AssociationSet i_fkeySet, EntitySet i_parentTable, EntitySet i_childTable, ReadOnlyMetadataCollection<EdmProperty> i_parentColumns, ReadOnlyMetadataCollection<EdmProperty> i_childColumns) { m_fKeySet = i_fkeySet; m_parentTable = i_parentTable; m_childTable = i_childTable; m_childColumns = new List<MemberPath>(); // Create parent and child paths using the table names foreach (EdmProperty property in i_childColumns) { MemberPath path = new MemberPath(m_childTable, property); m_childColumns.Add(path); } m_parentColumns = new List<MemberPath>(); foreach (EdmProperty property in i_parentColumns) { MemberPath path = new MemberPath(m_parentTable, property); m_parentColumns.Add(path); } }
/// <summary> /// Function for generating foreign key constraints. /// </summary> /// <param name="associationSet"></param> private void AppendCreateForeignKeys(AssociationSet associationSet) { var constraintBuilder = new StringBuilder(); Debug.Assert(associationSet.ElementType.ReferentialConstraints.Count == 1); // Get the constraint. var constraint = associationSet.ElementType.ReferentialConstraints[0]; // Principal (referenced) end of the constraint. var principalEnd = associationSet.AssociationSetEnds[constraint.FromRole.Name]; // Dependent (referencing) end of constraint. var dependentEnd = associationSet.AssociationSetEnds[constraint.ToRole.Name]; //If any of the participating entity sets was skipped, skip the association too if (ignoredEntitySets.Contains(principalEnd.EntitySet) || ignoredEntitySets.Contains(dependentEnd.EntitySet)) { constraintBuilder.Append("-- Ignoring association set with participating entity set with defining query: "); AppendIdentifierEscapeNewLine(constraintBuilder, associationSet.Name); constraintBuilder.AppendLine(); ignoredObjects.Add(constraintBuilder.ToString()); } else { constraintBuilder.Append("ALTER TABLE "); AppendIdentifier(constraintBuilder, GetTableName(dependentEnd.EntitySet)); constraintBuilder.Append(" ADD CONSTRAINT "); AppendIdentifier(constraintBuilder, associationSet.Name); constraintBuilder.Append(" FOREIGN KEY ("); AppendIdentifiers(constraintBuilder, constraint.ToProperties); // List of referencing columns. constraintBuilder.Append(") REFERENCES "); AppendIdentifier(constraintBuilder, GetTableName(principalEnd.EntitySet)); constraintBuilder.Append("("); AppendIdentifiers(constraintBuilder, constraint.FromProperties); // List of referenced columns. constraintBuilder.Append(")"); // Append cascade action if it exists. if (principalEnd.CorrespondingAssociationEndMember.DeleteBehavior == OperationAction.Cascade) { constraintBuilder.Append(" ON DELETE CASCADE"); } constraintBuilder.Append(";"); constraintBuilder.AppendLine(); constraints.Add(constraintBuilder.ToString()); } }
private void SaveAssociationForCollapsedAssociationCandidate(LoadMethodSessionState session, AssociationSet storeAssociationSet) { foreach (AssociationSetEnd end in storeAssociationSet.AssociationSetEnds) { OneToOneMappingSerializer.CollapsedEntityAssociationSet collapsed; if (session.CandidateCollapsedAssociations.TryGetValue(end.EntitySet, out collapsed)) { collapsed.AssociationSets.Add(storeAssociationSet); } } }
/// <summary> /// Construct a new AssociationSetMapping object /// </summary> /// <param name="extent">Represents the Association Set Metadata object. Will /// change this to Extent instead of MemberMetadata.</param> /// <param name="entityContainerMapping">The entityContainerMapping mapping that contains this Set mapping</param> internal StorageAssociationSetMapping(AssociationSet extent, StorageEntityContainerMapping entityContainerMapping) : base(extent, entityContainerMapping) { }
/// <summary> /// Converts an association set from SOM to metadata /// </summary> /// <param name="relationshipSet">The SOM element to process</param> /// <param name="providerManifest">The provider manifest to be used for conversion</param> /// <param name="convertedItemCache">The item collection for currently existing metadata objects</param> /// <param name="newGlobalItems">The new GlobalItem objects that are created as a result of this conversion</param> /// <param name="container"></param> /// <returns>The association set object resulting from the convert</returns> private static AssociationSet ConvertToAssociationSet(Som.EntityContainerRelationshipSet relationshipSet, DbProviderManifest providerManifest, ConversionCache convertedItemCache, EntityContainer container, Dictionary<Som.SchemaElement, GlobalItem> newGlobalItems) { Debug.Assert(relationshipSet.Relationship.RelationshipKind == RelationshipKind.Association); AssociationType associationType = (AssociationType)LoadSchemaElement((Som.SchemaType)relationshipSet.Relationship, providerManifest, convertedItemCache, newGlobalItems); AssociationSet associationSet = new AssociationSet(relationshipSet.Name, associationType); foreach (Som.EntityContainerRelationshipSetEnd end in relationshipSet.Ends) { //-- need the EntityType for the end EntityType endEntityType = (EntityType)LoadSchemaElement(end.EntitySet.EntityType, providerManifest, convertedItemCache, newGlobalItems); //-- need to get the end member AssociationEndMember endMember = (AssociationEndMember)associationType.Members[end.Name]; //-- create the end AssociationSetEnd associationSetEnd = new AssociationSetEnd(GetEntitySet(end.EntitySet, container), associationSet, endMember); AddOtherContent(end, associationSetEnd); associationSet.AddAssociationSetEnd(associationSetEnd); // Extract optional Documentation from the end element if (end.Documentation != null) { associationSetEnd.Documentation = ConvertToDocumentation(end.Documentation); } } // Extract the optional Documentation if (relationshipSet.Documentation != null) { associationSet.Documentation = ConvertToDocumentation(relationshipSet.Documentation); } AddOtherContent(relationshipSet, associationSet); return associationSet; }
private static AssociationSetEnd GetAssociationSetEndForForeignKeyTable(AssociationSet store) { ReferentialConstraint constraint = GetReferentialConstraint(store); return store.AssociationSetEnds.GetValue(constraint.ToRole.Name, false); }
internal static ReferentialConstraint GetReferentialConstraint(AssociationSet set) { // this seeems like a hack, but it is what we have right now. ReferentialConstraint constraint = null; foreach (ReferentialConstraint rc in set.ElementType.ReferentialConstraints) { Debug.Assert(constraint == null, "we should only get one"); constraint = rc; } Debug.Assert(constraint != null, "we should get at least one constraint"); return constraint; }
public override string WriteDropForeignKey(AssociationSet associationSet) { return string.Empty; }
private void WriteAssociationSetMappingElement(XmlWriter writer, AssociationSet store, AssociationSet model) { if (!model.ElementType.IsForeignKey) { writer.WriteStartElement(StorageMslConstructs.AssociationSetMappingElement, _xmlNamespace); writer.WriteAttributeString(StorageMslConstructs.AssociationSetMappingNameAttribute, model.Name); writer.WriteAttributeString(StorageMslConstructs.AssociationSetMappingTypeNameAttribute, model.ElementType.FullName); // all column names must be the primary key of the // end, but as columns in the Fk table. AssociationSetEnd foreignKeyTableEnd = GetAssociationSetEndForForeignKeyTable(store); writer.WriteAttributeString(StorageMslConstructs.AssociationSetMappingStoreEntitySetAttribute, foreignKeyTableEnd.EntitySet.Name); foreach (AssociationSetEnd storeEnd in store.AssociationSetEnds) { AssociationSetEnd modelEnd = _lookups.StoreAssociationSetEndToModelAssociationSetEnd[storeEnd]; WriteEndPropertyElement(writer, storeEnd, modelEnd); } ReferentialConstraint constraint = GetReferentialConstraint(store); foreach (EdmProperty fkColumn in constraint.ToProperties) { if (fkColumn.Nullable) { WriteConditionElement(writer, fkColumn); } } writer.WriteEndElement(); } }
private AssociationSet CreateModelAssociationSet(LoadMethodSessionState session, AssociationSet storeAssociationSet) { AssociationType association; // we will get a value when the same association is used for multiple association sets if (! session.MappingLookups.StoreAssociationTypeToModelAssociationType.TryGetValue(storeAssociationSet.ElementType, out association)) { association = CreateModelAssociationType(session, storeAssociationSet.ElementType); session.MappingLookups.StoreAssociationTypeToModelAssociationType.Add(storeAssociationSet.ElementType, association); } string name = CreateModelName(storeAssociationSet.Name, session.UsedEntityContainerItemNames); AssociationSet set = new AssociationSet(name, association); foreach(AssociationSetEnd storeEnd in storeAssociationSet.AssociationSetEnds) { AssociationSetEnd end = CreateModelAssociationSetEnd(session, storeEnd, set); session.MappingLookups.StoreAssociationSetEndToModelAssociationSetEnd.Add(storeEnd, end); set.AddAssociationSetEnd(end); } session.MappingLookups.StoreAssociationSetToModelAssociationSet.Add(storeAssociationSet, set); return set; }
/// <summary> /// Specialization of <see cref="CreatePlaceholder" /> for a relationship set extent. /// </summary> /// <param name="associationSet"></param> /// <returns></returns> private PropagatorResult CreateAssociationSetPlaceholder(AssociationSet associationSet) { Debug.Assert(null != associationSet, "Caller must verify parameters are not null"); var endMetadata = associationSet.ElementType.AssociationEndMembers; PropagatorResult[] endReferenceValues = new PropagatorResult[endMetadata.Count]; // Create a reference expression for each end in the relationship for (int endOrdinal = 0; endOrdinal < endMetadata.Count; endOrdinal++) { var end = endMetadata[endOrdinal]; EntityType entityType = (EntityType)((RefType)end.TypeUsage.EdmType).ElementType; // Retrieve key values for this end PropagatorResult[] keyValues = new PropagatorResult[entityType.KeyMembers.Count]; for (int memberOrdinal = 0; memberOrdinal < entityType.KeyMembers.Count; memberOrdinal++) { EdmMember keyMember = entityType.KeyMembers[memberOrdinal]; PropagatorResult keyValue = CreateMemberPlaceholder(keyMember); keyValues[memberOrdinal] = keyValue; } RowType endType = entityType.GetKeyRowType(m_parent.MetadataWorkspace); PropagatorResult refKeys = PropagatorResult.CreateStructuralValue(keyValues, endType, false); endReferenceValues[endOrdinal] = refKeys; } PropagatorResult result = PropagatorResult.CreateStructuralValue(endReferenceValues, associationSet.ElementType, false); return result; }
public virtual string WriteDropForeignKey(AssociationSet associationSet) { var constraint = associationSet.ElementType.ReferentialConstraints.Single(); var constraintName = GetForeignKeyConstraintName(constraint); var end = associationSet.AssociationSetEnds .Where(a => a.CorrespondingAssociationEndMember == constraint.ToRole) .Single(); var fqTableName = GetFullyQualifiedName(end.EntitySet.GetSchemaName(), end.EntitySet.GetTableName()); var name = FormatName(constraintName); return string.Format("ALTER TABLE {0} DROP CONSTRAINT {1};", fqTableName, name); }
// requires: IsForeignKeySuperSetOfPrimaryKeyInChildTable() is false // and primaryKeys of ChildTable are not mapped in cell. cell // corresponds to an association set. parentSet is the set // corresponding to the end that we are looking at // effects: Checks if the constraint is correctly maintained in // C-space via an association set (being a subset of the // corresponding entitySet) private bool CheckConstraintWhenOnlyParentMapped(Cell cell, EntitySet parentSet, AssociationSet assocSet, AssociationEndMember endMember, QueryRewriter childRewriter, QueryRewriter parentRewriter, ConfigViewGenerator config) { ViewgenContext childContext = childRewriter.ViewgenContext; ViewgenContext parentContext = parentRewriter.ViewgenContext; CellTreeNode pNode = parentRewriter.BasicView; Debug.Assert(pNode != null); RoleBoolean endRoleBoolean = new RoleBoolean(assocSet.AssociationSetEnds[endMember.Name]); // use query in pNode as a factory to create a bool expression for the endRoleBoolean BoolExpression endCondition = pNode.RightFragmentQuery.Condition.Create(endRoleBoolean); FragmentQuery cNodeQuery = FragmentQuery.Create(pNode.RightFragmentQuery.Attributes, endCondition); FragmentQueryProcessor qp = FragmentQueryProcessor.Merge(childContext.RightFragmentQP, parentContext.RightFragmentQP); bool cImpliesP = qp.IsContainedIn(cNodeQuery, pNode.RightFragmentQuery); return cImpliesP; }
internal StorageModificationFunctionMemberPath(IEnumerable<EdmMember> members, AssociationSet associationSetNavigation) { this.Members = new ReadOnlyCollection<EdmMember>(new List<EdmMember>( EntityUtil.CheckArgumentNull(members, "members"))); if (null != associationSetNavigation) { Debug.Assert(2 == this.Members.Count, "Association bindings must always consist of the end and the key"); // find the association set end this.AssociationSetEnd = associationSetNavigation.AssociationSetEnds[this.Members[1].Name]; } }
private AssociationSet CreateAssociationSet(LoadMethodSessionState session, AssociationType type) { AssociationSet set = new AssociationSet(type.Name, type); foreach(AssociationEndMember end in type.RelationshipEndMembers) { EntitySet entitySet = session.GetEntitySet(end); DbObjectKey key = session.GetKey(entitySet.ElementType); AssociationSetEnd setEnd = new AssociationSetEnd(entitySet, set, end); set.AddAssociationSetEnd(setEnd); } set.SetReadOnly(); return set; }
/// <summary> /// Initializes a new instance of AssocationSetEnd /// </summary> /// <param name="entitySet">Entity set that this end refers to</param> /// <param name="parentSet">The association set which this belongs to</param> /// <param name="endMember">The end member of the association set which this is an instance of</param> /// <exception cref="System.ArgumentNullException">Thrown if either the role,entitySet, parentSet or endMember arguments are null </exception> internal AssociationSetEnd(EntitySet entitySet, AssociationSet parentSet, AssociationEndMember endMember) { _entitySet = EntityUtil.GenericCheckArgumentNull(entitySet, "entitySet"); _parentSet = EntityUtil.GenericCheckArgumentNull(parentSet, "parentSet"); _endMember = EntityUtil.GenericCheckArgumentNull(endMember, "endMember"); }
private bool IsAssociationPartOfCandidateCollapsedAssociation(LoadMethodSessionState session, AssociationSet storeAssociationSet) { foreach (AssociationSetEnd end in storeAssociationSet.AssociationSetEnds) { if (session.CandidateCollapsedAssociations.ContainsKey(end.EntitySet)) { return true; } } return false; }
protected override void Visit(AssociationSet associationSet) { int index; if (!this.AddObjectToSeenListAndHashBuilder(associationSet, out index)) { return; } this.AddObjectStartDumpToHashBuilder(associationSet, index); #region Inner data visit this.AddObjectContentToHashBuilder(associationSet.CachedProviderSql); // Name is coverd by Identity this.AddObjectContentToHashBuilder(associationSet.Identity); this.AddObjectContentToHashBuilder(associationSet.Schema); this.AddObjectContentToHashBuilder(associationSet.Table); base.Visit(associationSet); #endregion this.AddObjectEndDumpToHashBuilder(); }
private AssociationSet CreateModelAssociationSet(LoadMethodSessionState session, OneToOneMappingSerializer.CollapsedEntityAssociationSet collapsedAssociationSet) { // create the association string associationName = CreateModelName(collapsedAssociationSet.EntitySet.Name, session.UsedGlobalModelTypeNames); AssociationType association = new AssociationType(associationName, _namespaceName, false, DataSpace.CSpace); // create the association set string associationSetName = CreateModelName(collapsedAssociationSet.EntitySet.Name, session.UsedEntityContainerItemNames); AssociationSet set = new AssociationSet(associationSetName, association); // create the association and association set end members UniqueIdentifierService usedEndMemberNames = new UniqueIdentifierService(false); for(int i = 0; i < collapsedAssociationSet.AssociationSets.Count; i++) { AssociationSetEnd storeEnd; RelationshipMultiplicity multiplicity; OperationAction deleteBehavior; collapsedAssociationSet.GetStoreAssociationSetEnd(i, out storeEnd, out multiplicity, out deleteBehavior); AssociationEndMember end = CreateAssociationEndMember(session, storeEnd.CorrespondingAssociationEndMember, usedEndMemberNames, multiplicity, deleteBehavior); association.AddMember(end); EntitySet entitySet = session.MappingLookups.StoreEntitySetToModelEntitySet[storeEnd.EntitySet]; AssociationSetEnd setEnd = new AssociationSetEnd(entitySet, set, end); set.AddAssociationSetEnd(setEnd); session.MappingLookups.StoreAssociationSetEndToModelAssociationSetEnd.Add(storeEnd, setEnd); } // don't need a referential constraint CreateModelNavigationProperties(session, association); collapsedAssociationSet.ModelAssociationSet = set; return set; }
// Helper method to determine if the specified entityKey is in the given role and AssociationSet in this relationship entry internal bool IsSameAssociationSetAndRole(AssociationSet associationSet, AssociationEndMember associationMember, EntityKey entityKey) { Debug.Assert(associationSet.ElementType.AssociationEndMembers[0].Name == associationMember.Name || associationSet.ElementType.AssociationEndMembers[1].Name == associationMember.Name, "Expected associationMember to be one of the ends of the specified associationSet."); if (!Object.ReferenceEquals(_entitySet, associationSet)) { return false; } // Find the end of the relationship that corresponds to the associationMember and see if it matches the EntityKey we are looking for if (_relationshipWrapper.AssociationSet.ElementType.AssociationEndMembers[0].Name == associationMember.Name) { return entityKey == Key0; } else { return entityKey == Key1; } }
private AssociationSetEnd CreateModelAssociationSetEnd(LoadMethodSessionState session, AssociationSetEnd storeEnd, AssociationSet parentModelAssociationSet) { AssociationEndMember associationEnd = session.MappingLookups.StoreAssociationEndMemberToModelAssociationEndMember[storeEnd.CorrespondingAssociationEndMember]; EntitySet entitySet = session.MappingLookups.StoreEntitySetToModelEntitySet[storeEnd.EntitySet]; string role = associationEnd.Name; AssociationSetEnd end = new AssociationSetEnd(entitySet, parentModelAssociationSet, associationEnd); return end; }
private static AssociationSetEnd GetAssociationSetEnd(AssociationSet set, bool fromEnd) { Debug.Assert(set.ElementType.ReferentialConstraints.Count == 1, "no referenctial constraint for association[0]"); ReferentialConstraint constraint = set.ElementType.ReferentialConstraints[0]; Debug.Assert(set.AssociationSetEnds.Count == 2, "Associations are assumed to have two ends"); int toEndIndex, fromEndIndex; if (set.AssociationSetEnds[0].CorrespondingAssociationEndMember == constraint.FromRole) { fromEndIndex = 0; toEndIndex = 1; } else { fromEndIndex = 1; toEndIndex = 0; } if (fromEnd) { return set.AssociationSetEnds[fromEndIndex]; } else { return set.AssociationSetEnds[toEndIndex]; } }
// requires: IsForeignKeySuperSetOfPrimaryKeyInChildTable() is false // and primaryKeys of ChildTable are not mapped in cell. cell // corresponds to an association set. parentSet is the set // corresponding to the end that we are looking at // effects: Checks if the constraint is correctly maintained in // C-space via an association set (being a subset of the // corresponding entitySet) private static bool CheckConstraintWhenOnlyParentMapped( AssociationSet assocSet, AssociationEndMember endMember, QueryRewriter childRewriter, QueryRewriter parentRewriter) { var childContext = childRewriter.ViewgenContext; var parentContext = parentRewriter.ViewgenContext; var pNode = parentRewriter.BasicView; Debug.Assert(pNode != null); var endRoleBoolean = new RoleBoolean(assocSet.AssociationSetEnds[endMember.Name]); // use query in pNode as a factory to create a bool expression for the endRoleBoolean var endCondition = pNode.RightFragmentQuery.Condition.Create(endRoleBoolean); var cNodeQuery = FragmentQuery.Create(pNode.RightFragmentQuery.Attributes, endCondition); var qp = FragmentQueryProcessor.Merge(childContext.RightFragmentQP, parentContext.RightFragmentQP); var cImpliesP = qp.IsContainedIn(cNodeQuery, pNode.RightFragmentQuery); return cImpliesP; }