/// <summary> /// DeletingRule: typeof(UniquenessConstraintIncludesColumn) /// If a uniqueness constraint column is being removed, then remove the corresponding column /// in any reference constraints that target the columns in the uniqueness constraint. /// </summary> private static void UniquenessConstraintColumnDeleting(ElementDeletingEventArgs e) { UniquenessConstraintIncludesColumn link = (UniquenessConstraintIncludesColumn)e.ModelElement; UniquenessConstraint uniquenessConstraint = link.UniquenessConstraint; if (!uniquenessConstraint.IsDeleting) { bool haveIndex = false; int index = -1; foreach (ReferenceConstraint referenceConstraint in uniquenessConstraint.ReferenceConstraintCollection) { if (!haveIndex) { haveIndex = true; index = UniquenessConstraintIncludesColumn.GetLinksToColumnCollection(uniquenessConstraint).IndexOf(link); } LinkedElementCollection <ColumnReference> columnRefs = referenceConstraint.ColumnReferenceCollection; if (index < columnRefs.Count && columnRefs[index].TargetColumn == link.Column) // Sanity check { columnRefs.RemoveAt(index); } else { // Something is off, delay validate this later ReferenceConstraintTargetsTable tableLink = ReferenceConstraintTargetsTable.GetLinkToTargetTable(referenceConstraint); if (tableLink != null) { FrameworkDomainModel.DelayValidateElement(tableLink, DelayValidateTargetUniquenessConstraint); } } } } }
/// <summary> /// AddRule: typeof(UniquenessConstraintIncludesColumn) /// Verify any related <see cref="ReferenceConstraint"/> when a new /// column is added to a uniqueness constraint. The reference constraint /// needs to be deleted if the calling code has not made a matching modification /// by the end of the transaction. /// </summary> private static void UniquenessConstraintColumnAdded(ElementAddedEventArgs e) { foreach (ReferenceConstraint referenceConstraint in ReferenceConstraintTargetsUniquenessConstraint.GetReferenceConstraintCollection(((UniquenessConstraintIncludesColumn)e.ModelElement).UniquenessConstraint)) { ReferenceConstraintTargetsTable tableLink = ReferenceConstraintTargetsTable.GetLinkToTargetTable(referenceConstraint); if (tableLink != null) { FrameworkDomainModel.DelayValidateElement(tableLink, DelayValidateTargetUniquenessConstraint); } } }
/// <summary> /// RolePlayerPositionChangeRule: typeof(UniquenessConstraintIncludesColumn) /// If a uniqueness constraint column is being repositioned, then reposition the corresponding column /// in any reference constraints that target the columns in the uniqueness constraint. /// </summary> private static void UniquenessConstraintColumnPositionChanged(RolePlayerOrderChangedEventArgs e) { if (e.CounterpartDomainRole.Id == UniquenessConstraintIncludesColumn.ColumnDomainRoleId) { UniquenessConstraint uniquenessConstraint = (UniquenessConstraint)e.SourceElement; int oldIndex = e.OldOrdinal; int newIndex = e.NewOrdinal; foreach (ReferenceConstraint referenceConstraint in uniquenessConstraint.ReferenceConstraintCollection) { LinkedElementCollection <ColumnReference> columnRefs = referenceConstraint.ColumnReferenceCollection; int columnRefCount = columnRefs.Count; if (newIndex < columnRefCount && oldIndex < columnRefCount && columnRefs[oldIndex].TargetColumn == e.CounterpartRolePlayer) // Sanity check { Column sourceColumn = columnRefs[oldIndex].SourceColumn; columnRefs.Move(oldIndex, newIndex); // Any uniqueness constraint that includes all columns in the // reference constraint will generate in a different order and // should be updated Table sourceTable; if (null != (sourceTable = referenceConstraint.SourceTable)) { foreach (UniquenessConstraint sourceUniquenessConstraint in sourceTable.UniquenessConstraintCollection) { LinkedElementCollection <Column> uniquenessColumns = sourceUniquenessConstraint.ColumnCollection; int uniquenessColumnCount = uniquenessColumns.Count; if (uniquenessColumnCount >= columnRefCount) { int firstMatchColumn = int.MaxValue; for (int i = 0; i < columnRefCount; ++i) { Column matchColumn = columnRefs[i].SourceColumn; int j = 0; for (; j < uniquenessColumnCount; ++j) { if (uniquenessColumns[j] == matchColumn) { firstMatchColumn = Math.Min(firstMatchColumn, j); break; } } if (j == uniquenessColumnCount) { // Not included firstMatchColumn = int.MaxValue; break; } } if (firstMatchColumn != int.MaxValue) { uniquenessColumnCount -= firstMatchColumn; if (newIndex < uniquenessColumnCount && oldIndex < uniquenessColumnCount && uniquenessColumns[firstMatchColumn + oldIndex] == sourceColumn) // Sanity check { uniquenessColumns.Move(firstMatchColumn + oldIndex, firstMatchColumn + newIndex); } // If this does not line up then something is clearly off, but // this is a non-critical error in that the model is still correctly // aligned and generates correct DDL. // However, the constraint will now have a different column order // than with a full regeneration. // UNDONE: Delay validation routine for this situation } } } } } else { // Something is off, delay validate this later ReferenceConstraintTargetsTable tableLink = ReferenceConstraintTargetsTable.GetLinkToTargetTable(referenceConstraint); if (tableLink != null) { FrameworkDomainModel.DelayValidateElement(tableLink, DelayValidateTargetUniquenessConstraint); } } } } }