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(ParentKey, 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);
}
}
}
}