// effects: Given the fact that rightKeyConstraint is not implied by a // leftSide key constraint, return a useful error message -- some S // was not implied by the C key constraints internal static ErrorLog.Record GetErrorRecord(ViewKeyConstraint rightKeyConstraint) { var keySlots = new List <ViewCellSlot>(rightKeyConstraint.KeySlots); var table = keySlots[0].SSlot.MemberPath.Extent; var cSet = keySlots[0].CSlot.MemberPath.Extent; var tablePrefix = new MemberPath(table); var cSetPrefix = new MemberPath(cSet); var tableKey = ExtentKey.GetPrimaryKeyForEntityType(tablePrefix, (EntityType)table.ElementType); ExtentKey cSetKey = null; if (cSet is EntitySet) { cSetKey = ExtentKey.GetPrimaryKeyForEntityType(cSetPrefix, (EntityType)cSet.ElementType); } else { cSetKey = ExtentKey.GetKeyForRelationType(cSetPrefix, (AssociationType)cSet.ElementType); } var message = Strings.ViewGen_KeyConstraint_Violation( table.Name, ViewCellSlot.SlotsToUserString(rightKeyConstraint.KeySlots, false /*isFromCside*/), tableKey.ToUserString(), cSet.Name, ViewCellSlot.SlotsToUserString(rightKeyConstraint.KeySlots, true /*isFromCside*/), cSetKey.ToUserString()); var debugMessage = StringUtil.FormatInvariant("PROBLEM: Not implied {0}", rightKeyConstraint); return(new ErrorLog.Record(ViewGenErrorCode.KeyConstraintViolation, message, rightKeyConstraint.CellRelation.Cell, debugMessage)); }
private static AssociationEndMember GetRelationEndForColumns( Cell cell, IEnumerable <MemberPath> columns) { if (cell.CQuery.Extent is EntitySet) { return((AssociationEndMember)null); } AssociationSet extent = (AssociationSet)cell.CQuery.Extent; foreach (AssociationSetEnd associationSetEnd in extent.AssociationSetEnds) { AssociationEndMember associationEndMember = associationSetEnd.CorrespondingAssociationEndMember; ExtentKey keyForEntityType = ExtentKey.GetPrimaryKeyForEntityType(new MemberPath((EntitySetBase)extent, (EdmMember)associationEndMember), associationSetEnd.EntitySet.ElementType); List <int> projectedPositions1 = cell.CQuery.GetProjectedPositions(keyForEntityType.KeyFields); if (projectedPositions1 != null) { List <int> projectedPositions2 = cell.SQuery.GetProjectedPositions(columns, projectedPositions1); if (projectedPositions2 != null && Helpers.IsSetEqual <int>((IEnumerable <int>)projectedPositions2, (IEnumerable <int>)projectedPositions1, (IEqualityComparer <int>)EqualityComparer <int> .Default)) { return(associationEndMember); } } } return((AssociationEndMember)null); }
// effects: Given the fact that none of the rightKeyConstraint are not implied by a // leftSide key constraint, return a useful error message (used for // the Update requirement internal static ErrorLog.Record GetErrorRecord(IEnumerable <ViewKeyConstraint> rightKeyConstraints) { ViewKeyConstraint rightKeyConstraint = null; var keyBuilder = new StringBuilder(); var isFirst = true; foreach (var rightConstraint in rightKeyConstraints) { var keyMsg = ViewCellSlot.SlotsToUserString(rightConstraint.KeySlots, true /*isFromCside*/); if (isFirst == false) { keyBuilder.Append("; "); } isFirst = false; keyBuilder.Append(keyMsg); rightKeyConstraint = rightConstraint; } var keySlots = new List <ViewCellSlot>(rightKeyConstraint.KeySlots); var table = keySlots[0].SSlot.MemberPath.Extent; var cSet = keySlots[0].CSlot.MemberPath.Extent; var tablePrefix = new MemberPath(table); var tableKey = ExtentKey.GetPrimaryKeyForEntityType(tablePrefix, (EntityType)table.ElementType); string message; if (cSet is EntitySet) { message = Strings.ViewGen_KeyConstraint_Update_Violation_EntitySet( keyBuilder.ToString(), cSet.Name, tableKey.ToUserString(), table.Name); } else { //For a 1:* or 0..1:* association, the * side has to be mapped to the //key properties of the table. Fior this specific case, we give out a specific message //that is specific for this case. var associationSet = (AssociationSet)cSet; var endMember = Helper.GetEndThatShouldBeMappedToKey(associationSet.ElementType); if (endMember != null) { message = Strings.ViewGen_AssociationEndShouldBeMappedToKey( endMember.Name, table.Name); } else { message = Strings.ViewGen_KeyConstraint_Update_Violation_AssociationSet( cSet.Name, tableKey.ToUserString(), table.Name); } } var debugMessage = StringUtil.FormatInvariant("PROBLEM: Not implied {0}", rightKeyConstraint); return(new ErrorLog.Record( ViewGenErrorCode.KeyConstraintUpdateViolation, message, rightKeyConstraint.CellRelation.Cell, debugMessage)); }
internal static ErrorLog.Record GetErrorRecord(ViewKeyConstraint rightKeyConstraint) { List <ViewCellSlot> viewCellSlotList = new List <ViewCellSlot>((IEnumerable <ViewCellSlot>)rightKeyConstraint.KeySlots); EntitySetBase extent1 = viewCellSlotList[0].SSlot.MemberPath.Extent; EntitySetBase extent2 = viewCellSlotList[0].CSlot.MemberPath.Extent; MemberPath prefix1 = new MemberPath(extent1); MemberPath prefix2 = new MemberPath(extent2); ExtentKey keyForEntityType = ExtentKey.GetPrimaryKeyForEntityType(prefix1, (EntityType)extent1.ElementType); ExtentKey extentKey = !(extent2 is EntitySet) ? ExtentKey.GetKeyForRelationType(prefix2, (AssociationType)extent2.ElementType) : ExtentKey.GetPrimaryKeyForEntityType(prefix2, (EntityType)extent2.ElementType); string message = Strings.ViewGen_KeyConstraint_Violation((object)extent1.Name, (object)ViewCellSlot.SlotsToUserString((IEnumerable <ViewCellSlot>)rightKeyConstraint.KeySlots, false), (object)keyForEntityType.ToUserString(), (object)extent2.Name, (object)ViewCellSlot.SlotsToUserString((IEnumerable <ViewCellSlot>)rightKeyConstraint.KeySlots, true), (object)extentKey.ToUserString()); string debugMessage = StringUtil.FormatInvariant("PROBLEM: Not implied {0}", (object)rightKeyConstraint); return(new ErrorLog.Record(ViewGenErrorCode.KeyConstraintViolation, message, rightKeyConstraint.CellRelation.Cell, debugMessage)); }
// effects: Returns the end to which columns are exactly mapped in the // relationship set given by cell.CQuery.Extent -- if this extent is // an entityset returns null. If the columns are not mapped in this cell to an // end exactly or columns are not projected in cell, returns null private static AssociationEndMember GetRelationEndForColumns(Cell cell, IEnumerable <MemberPath> columns) { if (cell.CQuery.Extent is EntitySet) { return(null); } var relationSet = (AssociationSet)cell.CQuery.Extent; // Go through all the ends and see if they are mapped in this cell foreach (var relationEnd in relationSet.AssociationSetEnds) { var endMember = relationEnd.CorrespondingAssociationEndMember; var prefix = new MemberPath(relationSet, endMember); // Note: primaryKey is the key for the entity set but // prefixed with the relationship's path - we are trying to // check if the entity's keys are mapped in this cell as an end var primaryKey = ExtentKey.GetPrimaryKeyForEntityType(prefix, relationEnd.EntitySet.ElementType); // Check if this end is mapped in this cell -- we are // checking on the C-side -- we get all the indexes of the // end's keyfields var endIndexes = cell.CQuery.GetProjectedPositions(primaryKey.KeyFields); if (endIndexes != null) { // Get all the slots corresponding to the columns // But stick to the slots with in these ends since the same column might be //projected twice in different ends var columnIndexes = cell.SQuery.GetProjectedPositions(columns, endIndexes); if (columnIndexes == null) { continue; // columns are not projected with in this end } // Note that the positions need not match exactly - we have a // separate test that will do that for us: CheckForeignKeyColumnOrder if (Helpers.IsSetEqual(columnIndexes, endIndexes, EqualityComparer <int> .Default)) { // The columns map exactly to this end -- return it return(endMember); } } } return(null); }
internal static ErrorLog.Record GetErrorRecord( IEnumerable <ViewKeyConstraint> rightKeyConstraints) { ViewKeyConstraint viewKeyConstraint = (ViewKeyConstraint)null; StringBuilder stringBuilder = new StringBuilder(); bool flag = true; foreach (ViewKeyConstraint rightKeyConstraint in rightKeyConstraints) { string userString = ViewCellSlot.SlotsToUserString((IEnumerable <ViewCellSlot>)rightKeyConstraint.KeySlots, true); if (!flag) { stringBuilder.Append("; "); } flag = false; stringBuilder.Append(userString); viewKeyConstraint = rightKeyConstraint; } List <ViewCellSlot> viewCellSlotList = new List <ViewCellSlot>((IEnumerable <ViewCellSlot>)viewKeyConstraint.KeySlots); EntitySetBase extent1 = viewCellSlotList[0].SSlot.MemberPath.Extent; EntitySetBase extent2 = viewCellSlotList[0].CSlot.MemberPath.Extent; ExtentKey keyForEntityType = ExtentKey.GetPrimaryKeyForEntityType(new MemberPath(extent1), (EntityType)extent1.ElementType); string message; if (extent2 is EntitySet) { message = Strings.ViewGen_KeyConstraint_Update_Violation_EntitySet((object)stringBuilder.ToString(), (object)extent2.Name, (object)keyForEntityType.ToUserString(), (object)extent1.Name); } else { AssociationEndMember shouldBeMappedToKey = Helper.GetEndThatShouldBeMappedToKey(((AssociationSet)extent2).ElementType); message = shouldBeMappedToKey == null?Strings.ViewGen_KeyConstraint_Update_Violation_AssociationSet((object)extent2.Name, (object)keyForEntityType.ToUserString(), (object)extent1.Name) : Strings.ViewGen_AssociationEndShouldBeMappedToKey((object)shouldBeMappedToKey.Name, (object)extent1.Name); } string debugMessage = StringUtil.FormatInvariant("PROBLEM: Not implied {0}", (object)viewKeyConstraint); return(new ErrorLog.Record(ViewGenErrorCode.KeyConstraintUpdateViolation, message, viewKeyConstraint.CellRelation.Cell, debugMessage)); }
// effects: Ensures that there is a relationship mapped into the C-space for some cell in m_cellGroup. Else // adds an error to errorLog private void GuaranteeMappedRelationshipForForeignKey( QueryRewriter childRewriter, QueryRewriter parentRewriter, IEnumerable <Cell> cells, ErrorLog errorLog, ConfigViewGenerator config) { var childContext = childRewriter.ViewgenContext; var parentContext = parentRewriter.ViewgenContext; // Find a cell where this foreign key is mapped as a relationship var prefix = new MemberPath(ChildTable); var primaryKey = ExtentKey.GetPrimaryKeyForEntityType(prefix, ChildTable.ElementType); var primaryKeyFields = primaryKey.KeyFields; var foundCell = false; var foundValidParentColumnsForForeignKey = false; //we need to find only one, dont error on any one check being false List <ErrorLog.Record> errorListForInvalidParentColumnsForForeignKey = null; foreach (var cell in cells) { if (cell.SQuery.Extent.Equals(ChildTable) == false) { continue; } // The childtable is mapped to a relationship in the C-space in cell // Check that all the columns of the foreign key and the primary key in the child table are mapped to some // property in the C-space var parentEnd = GetRelationEndForColumns(cell, ChildColumns); if (parentEnd != null && CheckParentColumnsForForeignKey(cell, cells, parentEnd, ref errorListForInvalidParentColumnsForForeignKey) == false) { // Not an error unless we find no valid case continue; } else { foundValidParentColumnsForForeignKey = true; } var childEnd = GetRelationEndForColumns(cell, primaryKeyFields); Debug.Assert( childEnd == null || parentEnd != childEnd, "Ends are same => PKey and child columns are same - code should gone to other method"); // Note: If both of them are not-null, they are mapped to the // same association set -- since we checked that particular cell if (childEnd != null && parentEnd != null && FindEntitySetForColumnsMappedToEntityKeys(cells, primaryKeyFields) != null) { foundCell = true; CheckConstraintWhenParentChildMapped(cell, errorLog, parentEnd, config); break; // Done processing for the foreign key - either it was mapped correctly or it was not } else if (parentEnd != null) { // At this point, we know cell corresponds to an association set var assocSet = (AssociationSet)cell.CQuery.Extent; var parentSet = MetadataHelper.GetEntitySetAtEnd(assocSet, parentEnd); foundCell = CheckConstraintWhenOnlyParentMapped(assocSet, parentEnd, childRewriter, parentRewriter); if (foundCell) { break; } } } //CheckParentColumnsForForeignKey has returned no matches, Error. if (!foundValidParentColumnsForForeignKey) { Debug.Assert( errorListForInvalidParentColumnsForForeignKey != null && errorListForInvalidParentColumnsForForeignKey.Count > 0); foreach (var errorRecord in errorListForInvalidParentColumnsForForeignKey) { errorLog.AddEntry(errorRecord); } return; } if (foundCell == false) { // No cell found -- Declare error var message = Strings.ViewGen_Foreign_Key_Missing_Relationship_Mapping(ToUserString()); IEnumerable <LeftCellWrapper> parentWrappers = GetWrappersFromContext(parentContext, ParentTable); IEnumerable <LeftCellWrapper> childWrappers = GetWrappersFromContext(childContext, ChildTable); var bothExtentWrappers = new Set <LeftCellWrapper>(parentWrappers); bothExtentWrappers.AddRange(childWrappers); var record = new ErrorLog.Record( ViewGenErrorCode.ForeignKeyMissingRelationshipMapping, message, bothExtentWrappers, String.Empty); errorLog.AddEntry(record); } }
private void GuaranteeMappedRelationshipForForeignKey( QueryRewriter childRewriter, QueryRewriter parentRewriter, IEnumerable <Cell> cells, ErrorLog errorLog, ConfigViewGenerator config) { ViewgenContext viewgenContext1 = childRewriter.ViewgenContext; ViewgenContext viewgenContext2 = parentRewriter.ViewgenContext; IEnumerable <MemberPath> keyFields = ExtentKey.GetPrimaryKeyForEntityType(new MemberPath((EntitySetBase)this.ChildTable), this.ChildTable.ElementType).KeyFields; bool flag1 = false; bool flag2 = false; List <ErrorLog.Record> errorList = (List <ErrorLog.Record>)null; foreach (Cell cell in cells) { if (cell.SQuery.Extent.Equals((object)this.ChildTable)) { AssociationEndMember relationEndForColumns = ForeignConstraint.GetRelationEndForColumns(cell, this.ChildColumns); if (relationEndForColumns == null || this.CheckParentColumnsForForeignKey(cell, cells, relationEndForColumns, ref errorList)) { flag2 = true; if (ForeignConstraint.GetRelationEndForColumns(cell, keyFields) != null && relationEndForColumns != null && ForeignConstraint.FindEntitySetForColumnsMappedToEntityKeys(cells, keyFields).Count > 0) { flag1 = true; this.CheckConstraintWhenParentChildMapped(cell, errorLog, relationEndForColumns, config); break; } if (relationEndForColumns != null) { AssociationSet extent = (AssociationSet)cell.CQuery.Extent; MetadataHelper.GetEntitySetAtEnd(extent, relationEndForColumns); flag1 = ForeignConstraint.CheckConstraintWhenOnlyParentMapped(extent, relationEndForColumns, childRewriter, parentRewriter); if (flag1) { break; } } } } } if (!flag2) { foreach (ErrorLog.Record record in errorList) { errorLog.AddEntry(record); } } else { if (flag1) { return; } string message = Strings.ViewGen_Foreign_Key_Missing_Relationship_Mapping((object)this.ToUserString()); IEnumerable <LeftCellWrapper> wrappersFromContext1 = (IEnumerable <LeftCellWrapper>)ForeignConstraint.GetWrappersFromContext(viewgenContext2, (EntitySetBase)this.ParentTable); IEnumerable <LeftCellWrapper> wrappersFromContext2 = (IEnumerable <LeftCellWrapper>)ForeignConstraint.GetWrappersFromContext(viewgenContext1, (EntitySetBase)this.ChildTable); Set <LeftCellWrapper> set = new Set <LeftCellWrapper>(wrappersFromContext1); set.AddRange(wrappersFromContext2); ErrorLog.Record record = new ErrorLog.Record(ViewGenErrorCode.ForeignKeyMissingRelationshipMapping, message, (IEnumerable <LeftCellWrapper>)set, string.Empty); errorLog.AddEntry(record); } }