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> /// Add the rel property induced by the specified relationship, (if the target /// end has a multiplicity of one) /// We only keep track of rel-properties that are "interesting" /// </summary> /// <param name="associationType">the association relationship</param> /// <param name="fromEnd">source end of the relationship traversal</param> /// <param name="toEnd">target end of the traversal</param> private void AddRelProperty( AssociationType associationType, AssociationEndMember fromEnd, AssociationEndMember toEnd) { if (toEnd.RelationshipMultiplicity == RelationshipMultiplicity.Many) { return; } var prop = new RelProperty(associationType, fromEnd, toEnd); if (_interestingRelProperties == null || !_interestingRelProperties.Contains(prop)) { return; } var entityType = ((RefType)fromEnd.TypeUsage.EdmType).ElementType; List<RelProperty> propList; if (!_relPropertyMap.TryGetValue(entityType, out propList)) { propList = new List<RelProperty>(); _relPropertyMap[entityType] = propList; } propList.Add(prop); }
public static AssociationEndMember GetOtherAssociationEnd( this ObjectStateEntry entry, AssociationEndMember end) { end.ValidateBelongsTo(entry); AssociationEndMember[] ends = entry.GetAssociationEnds(); if (ends[0] == end) { return ends[1]; } return ends[0]; }
internal string GetNavigationPropertyName(AssociationEndMember toEnd, string storeTableName) { if (this.Service != null) { return toEnd.RelationshipMultiplicity == RelationshipMultiplicity.Many ? this.Service.Pluralize(storeTableName) : this.Service.Singularize(storeTableName); } else { return storeTableName; } }
public static NavigationProperty GetNavigationProperty(this ObjectStateEntry entry, AssociationEndMember end) { end.ValidateBelongsTo(entry); var otherEnd = entry.GetOtherAssociationEnd(end); var relationshipType = entry.EntitySet.ElementType; EntityType elementType = GetInheritedEntityTypeByEntityName(entry, end.Name); NavigationProperty property = elementType.NavigationProperties.SingleOrDefault(p => p.RelationshipType == relationshipType && p.FromEndMember == end && p.ToEndMember == otherEnd); return property; }
public static EntityKey GetEndEntityKey(this ObjectStateEntry entry, AssociationEndMember end) { end.ValidateBelongsTo(entry); AssociationEndMember[] ends = entry.GetAssociationEnds(); if (ends[0] == end) { return entry.UsableValues()[0] as EntityKey; } return entry.UsableValues()[1] as EntityKey; }
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; }
private void CreateModelNavigationProperty(LoadMethodSessionState session, AssociationEndMember from, AssociationEndMember to) { EntityType entityType = (EntityType)((RefType)from.TypeUsage.EdmType).ElementType; UniqueIdentifierService usedMemberNames = new UniqueIdentifierService(false); LoadNameLookupWithUsedMemberNames(entityType, usedMemberNames); string name = CreateModelName(this._pluralizationServiceHandler.GetNavigationPropertyName(to, to.Name), usedMemberNames); NavigationProperty navigationProperty = new NavigationProperty(name, to.TypeUsage); navigationProperty.RelationshipType = (AssociationType)to.DeclaringType; navigationProperty.ToEndMember = to; navigationProperty.FromEndMember = from; entityType.AddMember(navigationProperty); }
private AssociationEndMember CreateAssociationEndMember(LoadMethodSessionState session, AssociationEndMember storeEndMember, KeyValuePair<string, RelationshipMultiplicity> endMultiplicityOverride, UniqueIdentifierService usedEndMemberNames) { RelationshipMultiplicity multiplicity = storeEndMember.RelationshipMultiplicity; if (endMultiplicityOverride.Key != null && endMultiplicityOverride.Key == storeEndMember.Name) { multiplicity = endMultiplicityOverride.Value; } return CreateAssociationEndMember(session, storeEndMember, usedEndMemberNames, multiplicity, storeEndMember.DeleteBehavior); }
/// <summary> /// Constrcut a new AssociationEnd member mapping metadata object /// </summary> /// <param name="edmAssociationEnd"></param> /// <param name="clrAssociationEnd"></param> internal ObjectAssociationEndMapping(AssociationEndMember edmAssociationEnd, AssociationEndMember clrAssociationEnd) : base(edmAssociationEnd, clrAssociationEnd) { }
// 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; }
protected virtual void Visit(AssociationEndMember associationEndMember) { Visit(associationEndMember.TypeUsage); }
private CodeTypeOfExpression GetEndTypeCodeExpression(AssociationEndMember end) { return new CodeTypeOfExpression(Generator.GetFullyQualifiedTypeReference(((RefType)end.TypeUsage.EdmType).ElementType)); }
// 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; }
/// <summary> /// Determines whether the specified { from, to } relationship end pairing represents a navigation that is /// valid for a relationship span sourced by an instance of the specified entity type. /// </summary> /// <param name="compareType">The Entity type which valid 'from' ends must reference (or a supertype of that Entity type)</param> /// <param name="associationType">The Association type to consider.</param> /// <param name="fromEnd">The candidate 'from' end, which will be checked based on the Entity type it references</param> /// <param name="toEnd">The candidate 'to' end, which will be checked base on the upper bound of its multiplicity</param> /// <returns> /// <c>True</c> if the end pairing represents a valid navigation from an instance of the specified entity type /// to an association end with a multiplicity upper bound of at most 1; otherwise <c>false</c> /// </returns> private static bool IsValidRelationshipSpan(EntityType compareType, AssociationType associationType, AssociationEndMember fromEnd, AssociationEndMember toEnd) { // Only a relationship end with a multiplicity of AT MOST one may be // considered as the 'to' end, so that the cardinality of the result // of the relationship span has an upper bound of 1. // Therefore ends with RelationshipMultiplicity of EITHER One OR ZeroOrOne // are the only ends that should be considered as target ends. // Note that a relationship span can be sourced by an Entity that is of the same type // as the Entity type referenced by the 'from' end OR any type in the same branch of // the type hierarchy. // // For example, in the following hierarchy: // // A (*<-->?) AOwner // |_B (*<-->1) BOwner // |_A1 (*<-->?) A1Owner // |_A2 // |_A3_1 (1<-->?) A3_1Owner // |_A3_2 (*<-->1) A3_2Owner // // An instance of 'A' would need ALL the 'AOwner', 'BOwner', 'A1Owner', 'A3_1Owner' and 'A3_2Owner' ends // spanned in because an instance of 'A' could actually be an instance of A, B, A1, A2, A3_1 or A3_2. // An instance of 'B' would only need 'AOwner' and 'BOwner' spanned in. // An instance of A2 would need 'AOwner', 'A1Owner', 'A3_1Owner' and 'A3_2Owner' spanned in. // An instance of A3_1 would only need 'AOwner', 'A1Owner' and 'A3_1Owner' spanned in. // // In general, the rule for relationship span is: // - 'To' end cardinality AT MOST one // AND // - Referenced Entity type of 'From' end is equal to instance Entity type // OR // - Referenced Entity type of 'From' end is a supertype of instance Entity type // OR // - Referenced Entity type of 'From' end is a subtype of instance Entity type // (this follows from the fact that an instance of 'A' may be an instance of any of its derived types. // Navigation for a subtype relationship will return null if the Entity instance navigation source // is not actually of the required subtype). // if(!associationType.IsForeignKey && (RelationshipMultiplicity.One == toEnd.RelationshipMultiplicity || RelationshipMultiplicity.ZeroOrOne == toEnd.RelationshipMultiplicity)) { EntityType fromEntityType = (EntityType)((RefType)fromEnd.TypeUsage.EdmType).ElementType; return (ObjectSpanRewriter.EntityTypeEquals(compareType, fromEntityType) || TypeSemantics.IsSubTypeOf(compareType, fromEntityType) || TypeSemantics.IsSubTypeOf(fromEntityType, compareType)); } return false; }
// effects : Return the slot numbers for members in Cell Query that // represent the association end member passed in. internal List<int> GetAssociationEndSlots(AssociationEndMember endMember) { var slotIndexes = new List<int>(); Debug.Assert(Extent is AssociationSet); for (var i = 0; i < m_projectedSlots.Length; i++) { var slot = m_projectedSlots[i] as MemberProjectedSlot; if (slot != null && slot.MemberPath.RootEdmMember.Equals(endMember)) { slotIndexes.Add(i); } } return slotIndexes; }
/// <summary> /// True if the specified association end is the principal in an identifying relationship. /// or if the association end has cascade delete defined. /// </summary> public bool IsCascadeDeletePrincipal(AssociationEndMember associationEnd) { if (associationEnd == null) { throw new ArgumentNullException("associationEnd"); } return associationEnd.DeleteBehavior == OperationAction.Cascade || IsPrincipalEndOfIdentifyingRelationship(associationEnd); }
private bool CreateReferentialConstraint(LoadMethodSessionState session, AssociationType association, AssociationEndMember pkEnd, AssociationEndMember fkEnd, List<RelationshipDetailsRow> columns, List<EdmSchemaError> errors) { EdmProperty[] fromProperties = new EdmProperty[columns.Count]; EdmProperty[] toProperties = new EdmProperty[columns.Count]; EntityType pkEntityType = session.RelationshipEndTypeLookup[pkEnd]; EntityType fkEntityType = session.RelationshipEndTypeLookup[fkEnd]; for (int index = 0; index < columns.Count; index++) { EdmProperty property; if(!pkEntityType.Properties.TryGetValue(columns[index].PKColumn, false, out property)) { errors.Add( new EdmSchemaError( Strings.AssociationMissingKeyColumn( pkEntityType.Name, fkEntityType.Name, pkEntityType.Name + "." + columns[index].PKColumn), (int)ModelBuilderErrorCode.AssociationMissingKeyColumn, EdmSchemaErrorSeverity.Warning)); return false; } fromProperties[index] = property; if(!fkEntityType.Properties.TryGetValue(columns[index].FKColumn, false, out property)) { errors.Add( new EdmSchemaError( Strings.AssociationMissingKeyColumn( pkEntityType.Name, fkEntityType.Name, fkEntityType.Name + "." + columns[index].FKColumn), (int)ModelBuilderErrorCode.AssociationMissingKeyColumn, EdmSchemaErrorSeverity.Warning)); return false; } toProperties[index] = property; } ReferentialConstraint constraint = new ReferentialConstraint(pkEnd, fkEnd, fromProperties, toProperties); association.AddReferentialConstraint(constraint); return true; }
protected override void Visit(AssociationEndMember associationEndMember) { int index; if (!this.AddObjectToSeenListAndHashBuilder(associationEndMember, out index)) { return; } this.AddObjectStartDumpToHashBuilder(associationEndMember, index); #region Inner data visit this.AddObjectContentToHashBuilder(associationEndMember.DeleteBehavior); this.AddObjectContentToHashBuilder(associationEndMember.Identity); // Name is covered by Identity this.AddObjectContentToHashBuilder(associationEndMember.IsStoreGeneratedComputed); this.AddObjectContentToHashBuilder(associationEndMember.IsStoreGeneratedIdentity); this.AddObjectContentToHashBuilder(associationEndMember.RelationshipMultiplicity); base.Visit(associationEndMember); #endregion this.AddObjectEndDumpToHashBuilder(); }
private static void ProcessReferenceCandidate( EntityKey source, HashSet<IEntityStateEntry> stateEntries, Dictionary<AssociationEndMember, IEntityStateEntry> currentReferenceEnd, Dictionary<AssociationEndMember, IEntityStateEntry> originalReferenceEnd, AssociationEndMember endMember, IEntityStateEntry candidateEntry) { Func<DbDataRecord, int, EntityKey> getEntityKey = (record, ordinal) => (EntityKey)record[ordinal]; Action<DbDataRecord, Action<IEntityStateEntry>> findMatch = (record, registerTarget) => { // find the end corresponding to the 'to' end int toOrdinal = record.GetOrdinal(endMember.Name); Debug.Assert(-1 != toOrdinal, "to end of relationship doesn't exist in record"); // the 'from' end must be the other end int fromOrdinal = 0 == toOrdinal ? 1 : 0; if (getEntityKey(record, fromOrdinal) == source) { stateEntries.Add(candidateEntry); registerTarget(candidateEntry); } }; switch (candidateEntry.State) { case EntityState.Unchanged: findMatch( candidateEntry.CurrentValues, (target) => { currentReferenceEnd.Add(endMember, target); originalReferenceEnd.Add(endMember, target); }); break; case EntityState.Added: findMatch( candidateEntry.CurrentValues, (target) => currentReferenceEnd.Add(endMember, target)); break; case EntityState.Deleted: findMatch( candidateEntry.OriginalValues, (target) => originalReferenceEnd.Add(endMember, target)); break; default: break; } }
private AssociationEndMember CreateAssociationEndMember(LoadMethodSessionState session, AssociationEndMember storeEndMember, UniqueIdentifierService usedEndMemberNames, RelationshipMultiplicity multiplicityOverride, OperationAction deleteBehaviorOverride) { Debug.Assert(storeEndMember.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.RefType, "The type is not a ref type"); Debug.Assert(((RefType)storeEndMember.TypeUsage.EdmType).ElementType.BuiltInTypeKind == BuiltInTypeKind.EntityType, "the ref is not holding on to an EntityType"); EntityType storeEntityType = ((EntityType)((RefType)storeEndMember.TypeUsage.EdmType).ElementType); EntityType modelEntityType = session.MappingLookups.StoreEntityTypeToModelEntityType[storeEntityType]; string name = CreateModelName(storeEndMember.Name, usedEndMemberNames); AssociationEndMember end = new AssociationEndMember(name, modelEntityType.GetReferenceType(), multiplicityOverride); end.DeleteBehavior = deleteBehaviorOverride; return end; }
// effects: Given the foreign key constraint, checks if the // constraint.ParentColumns are mapped to the entity set E'e keys in // C-space where E corresponds to the entity set corresponding to end // Returns true iff such a mapping exists in cell private bool CheckParentColumnsForForeignKey( Cell cell, IEnumerable<Cell> cells, AssociationEndMember parentEnd, ref List<ErrorLog.Record> errorList) { // The child columns are mapped to some end of cell.CQuery.Extent. ParentColumns // must correspond to the EntitySet for this end var relationSet = (AssociationSet)cell.CQuery.Extent; var endSet = MetadataHelper.GetEntitySetAtEnd(relationSet, parentEnd); // Check if the ParentColumns are mapped to endSet's keys // Find the entity set that they map to - if any var entitySet = FindEntitySetForColumnsMappedToEntityKeys(cells, ParentColumns); if (entitySet == null || endSet.Equals(entitySet) == false) { if (errorList == null) //lazily initialize only if there is an error { errorList = new List<ErrorLog.Record>(); } // childColumns are mapped to parentEnd but ParentColumns are not mapped to the end // corresponding to the parentEnd -- this is an error var message = Strings.ViewGen_Foreign_Key_ParentTable_NotMappedToEnd( ToUserString(), ChildTable.Name, cell.CQuery.Extent.Name, parentEnd.Name, ParentTable.Name, endSet.Name); var record = new ErrorLog.Record(ViewGenErrorCode.ForeignKeyParentTableNotMappedToEnd, message, cell, String.Empty); errorList.Add(record); return false; } return true; }
private bool TryGetNavigationSource(AssociationEndMember wasSourceNowTargetEnd, out DbExpression source) { source = null; NavigationInfo info = null; if (_navSources.Count > 0) { info = _navSources.Peek(); if (info != null && !object.ReferenceEquals(wasSourceNowTargetEnd, info.SourceEnd)) { info = null; } } if (info != null) { source = info.SourceVariable; info.InUse = true; return true; } else { return false; } }
private AssociationEndMember CreateAssociationEnd(LoadMethodSessionState session, EntityType type, RelationshipMultiplicity multiplicity, UniqueIdentifierService usedEndNames, OperationAction deleteAction ) { string role = usedEndNames.AdjustIdentifier(type.Name); RefType refType = type.GetReferenceType(); AssociationEndMember end = new AssociationEndMember(role, refType, multiplicity); end.DeleteBehavior = deleteAction; session.RelationshipEndTypeLookup.Add(end, type); return end; }
public NavigationInfo(DbRelationshipNavigationExpression originalNavigation, DbRelationshipNavigationExpression rewrittenNavigation) { Debug.Assert(originalNavigation != null, "originalNavigation cannot be null"); Debug.Assert(rewrittenNavigation != null, "rewrittenNavigation cannot be null"); this._original = originalNavigation; this._rewritten = rewrittenNavigation; this._sourceEnd = (AssociationEndMember)originalNavigation.NavigateFrom; this._sourceRef = (DbVariableReferenceExpression)rewrittenNavigation.NavigationSource; this._source = originalNavigation.NavigationSource; }
/// <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"); }
/// <summary> /// True if the specified association end is the principal end in an identifying relationship. /// In order to be an identifying relationship, the association must have a referential constraint where all of the dependent properties are part of the dependent type's primary key. /// </summary> public bool IsPrincipalEndOfIdentifyingRelationship(AssociationEndMember associationEnd) { if (associationEnd == null) { throw new ArgumentNullException("associationEnd"); } ReferentialConstraint refConstraint = ((AssociationType)associationEnd.DeclaringType).ReferentialConstraints.Where(rc => rc.FromRole == associationEnd).SingleOrDefault(); if (refConstraint != null) { EntityType entity = refConstraint.ToRole.GetEntityType(); return !refConstraint.ToProperties.Where(tp => !entity.KeyMembers.Contains(tp)).Any(); } return false; }
// 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; } }
// requires: IsForeignKeySuperSetOfPrimaryKeyInChildTable() is false // effects: Given that both the ChildColumns in this and the // primaryKey of ChildTable are mapped. Return true iff no error occurred private bool CheckConstraintWhenParentChildMapped( Cell cell, ErrorLog errorLog, AssociationEndMember parentEnd, ConfigViewGenerator config) { var ok = true; // The foreign key constraint has been mapped to a // relationship. Check if the multiplicities are consistent // If all columns in the child table (corresponding to // the constraint) are nullable, the parent end can be // 0..1 or 1..1. Else if must be 1..1 if (parentEnd.RelationshipMultiplicity == RelationshipMultiplicity.Many) { // Parent should at most one since we are talking // about foreign keys here var message = Strings.ViewGen_Foreign_Key_UpperBound_MustBeOne( ToUserString(), cell.CQuery.Extent.Name, parentEnd.Name); var record = new ErrorLog.Record(ViewGenErrorCode.ForeignKeyUpperBoundMustBeOne, message, cell, String.Empty); errorLog.AddEntry(record); ok = false; } if (MemberPath.AreAllMembersNullable(ChildColumns) == false && parentEnd.RelationshipMultiplicity != RelationshipMultiplicity.One) { // Some column in the constraint in the child table // is non-nullable and lower bound is not 1 var message = Strings.ViewGen_Foreign_Key_LowerBound_MustBeOne( ToUserString(), cell.CQuery.Extent.Name, parentEnd.Name); var record = new ErrorLog.Record(ViewGenErrorCode.ForeignKeyLowerBoundMustBeOne, message, cell, String.Empty); errorLog.AddEntry(record); ok = false; } if (config.IsNormalTracing && ok) { Trace.WriteLine("Foreign key mapped to relationship " + cell.CQuery.Extent.Name); } return ok; }
static private void AddEnd(ref Set<AssociationEndMember> set, AssociationEndMember element) { if (null == set) { set = new Set<AssociationEndMember>(); } set.Add(element); }
/// <summary> /// Initialize the end member if its not initialized already /// </summary> /// <param name="associationType"></param> /// <param name="end"></param> /// <param name="endMemberType"></param> private static AssociationEndMember InitializeAssociationEndMember(AssociationType associationType, Som.IRelationshipEnd end, EntityType endMemberType) { AssociationEndMember associationEnd; EdmMember member; // make sure that the end is not initialized as of yet if (!associationType.Members.TryGetValue(end.Name, false/*ignoreCase*/, out member)) { // Create the end member and add the operations associationEnd = new AssociationEndMember(end.Name, endMemberType.GetReferenceType(), end.Multiplicity.Value); associationType.AddKeyMember(associationEnd); } else { associationEnd = (AssociationEndMember)member; } //Extract the optional Documentation Som.RelationshipEnd relationshipEnd = end as Som.RelationshipEnd; if (relationshipEnd != null && (relationshipEnd.Documentation != null)) { associationEnd.Documentation = ConvertToDocumentation(relationshipEnd.Documentation); } return associationEnd; }