Two days ago, I have asked this question on how to modify deletion rules of foreign key constraints at runtime. That question has been answered, but now I would like to generalise my program:
Currently I have:
try
{
dt_MainTable1.Rows[0].Delete();
}
catch (Exception ex)
{
if (MessageBox.Show("In order to avoid data corruption, not only " +
" the required tupple will be deleted, " +
"but also the ones in other tables, " +
"referring to that tupple. " +
"Is that what you want?",
"Warning",
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
(ForeignKeyConstraint)(dt_SubTable1.Constraints[0]).DeleteRule
= Rule.Cascade;
dt_MainTable1.Rows[0].Delete();
(ForeignKeyConstraint)(dt_SubTable1.Constraints[0]).DeleteRule
= Rule.None;
}
}
... and this is what I would like to have: I try to do something (like a modification or a deletion), but I fall into a System.Data.InvalidConstraintException
, based on a Constraint
. Then I ask a question and based on the answer I turn the impacted Constraint
's Deletion Rule
or Modification Rule
into None
or Cascade
. The big problem: can I retrieve the impacted Constraint
from the generated System.Data.InvalidConstraintException
? (I've been debugging and checking the properties of the System.Data.InvalidConstraintException
, but I didn't find anything), just to show what I want (see the ex.FindRelevantConstraints()
method):
try
{
LaunchDeleteAction(...);
}
catch (Exception ex)
{
if (MessageBox.Show("In order to avoid data corruption, not only " +
" the required tupple will be deleted, " +
"but also the ones in other tables, " +
"referring to that tupple. " +
"Is that what you want?",
"Warning",
MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
for each (ForeignKeyConstraint C in ex.FindRelevantConstraints() <===
C.DeleteRule = Rule.Cascade;
LaunchDeleteAction(...);
for each (ForeignKeyConstraint C in ex.FindRelevantConstraints() <===
C.DeleteRule = Rule.None;
}
}
Edit after some more investigation
Meanwhile I've found out that the Exception
, ex
, contains the name of the corresponding Constraint
, as you can see in following watch window excerpt:
ex.Message : Cannot delete this row because constraints are enforced on relation Constraint1, and deleting this row will strand child rows.
I mean, it can't possibly be the intention to parse the Exception
's message in order to get a reference to the Constraint
object I'm looking for?
Desperate edit
In the meantime, I've decided to give special names to the Constraint
objects I'm creating, like you can see here:
dt_SubTable1.Constraints.Add(
new ForeignKeyConstraint("|FKC|MainTable.SubId|SubTable.Id|",
dt_SubTable.Columns["Id"],
dt_MainTable.Columns["SubId"])
{ DeleteRule = Rule.None,
UpdateRule = Rule.None });
As you can see, I can use the pipe character for separating the table names and the dots for finding the column names, but that's really a desperate idea :-)