internal override void CheckConstraint(DataRow childRow, DataRowAction action)
{
if ((action == DataRowAction.Change ||
action == DataRowAction.Add ||
action == DataRowAction.Rollback) &&
Table.DataSet != null && Table.DataSet.EnforceConstraints &&
childRow.HasKeyChanged(childKey))
{
// This branch is for cascading case verification.
DataRowVersion version = (action == DataRowAction.Rollback) ? DataRowVersion.Original : DataRowVersion.Current;
object[] childKeyValues = childRow.GetKeyValues(childKey);
// check to see if this is just a change to my parent's proposed value.
if (childRow.HasVersion(version))
{
// this is the new proposed value for the parent.
DataRow parentRow = DataRelation.GetParentRow(this.ParentKey, this.ChildKey, childRow, version);
if (parentRow != null && parentRow.inCascade)
{
object[] parentKeyValues = parentRow.GetKeyValues(parentKey, action == DataRowAction.Rollback ? version : DataRowVersion.Default);
int parentKeyValuesRecord = childRow.Table.NewRecord();
childRow.Table.SetKeyValues(childKey, parentKeyValues, parentKeyValuesRecord);
if (childKey.RecordsEqual(childRow.tempRecord, parentKeyValuesRecord))
{
return;
}
}
}
// now check to see if someone exists... it will have to be in a parent row's current, not a proposed.
object[] childValues = childRow.GetKeyValues(childKey);
if (!IsKeyNull(childValues))
{
Index parentIndex = parentKey.GetSortIndex();
if (!parentIndex.IsKeyInIndex(childValues))
{
// could be self-join constraint
if (childKey.Table == parentKey.Table && childRow.tempRecord != -1)
{
int lo = 0;
for (lo = 0; lo < childValues.Length; lo++)
{
DataColumn column = parentKey.ColumnsReference[lo];
object value = column.ConvertValue(childValues[lo]);
if (0 != column.CompareValueTo(childRow.tempRecord, value))
{
break;
}
}
if (lo == childValues.Length)
{
return;
}
}
throw ExceptionBuilder.ForeignKeyViolation(ConstraintName, childKeyValues);
}
}
}
}