如何处理基于 ForeignKeyConstraint 的删除触发异常?

How to treat deletion triggered exceptions, based on a ForeignKeyConstraint?

昨天 ,建议的解决方案运行良好。

现在我有以下用于创建 ForeinKeyConstraint 的源代码行(为了便于阅读,分为多行):

dt_Locations.Constraints.Add(
  new ForeignKeyConstraint(dt_Areas.Columns["Id"], 
                           dt_Locations.Columns["AreaId"]) 
  { 
     DeleteRule = Rule.None, 
     UpdateRule = Rule.None
  }
);

当我尝试从 DataTable dt_Areas 中删除一行时,它被 DataTable dt_Locations 条目引用,我得到一个异常:

try
{ 
  dt_Areas.Rows[0].Delete();
}
catch (Exception ex)
{
  MessageBox.Show($"You can't do that: [{dt_Locations.Constraints[0].ToString()}] and [{ex.Message}]");
}

现在,故事的下一部分:我想将消息框更改为:

"You want to remove 'Area' tupples which are being referred to by 'Locations' tupples. Do you want to remove those 'Locations' tupples and remove the 'Area' tupples afterwards?"

此消息在 MessageBox 构造函数中显示为 MessageBoxButton.YesNo

为了执行此删除操作,我需要:

dt_Areas.TableName;
dt_Locations.TableName;
dt_Areas.Columns["AreasId"].Ordinal;     // in order to know which column I need to take the value from
                                         // that I need for searching in the Locations table.
dt_Locations.Constraints[0].<properties> // properties: "RelatedColumns", "RelatedTable", "Table", ...

我有能力做到这一点,但这看起来是一个巨大的负担,我几乎不敢相信 .Net 平台没有提供这样的功能。

我说的对吗?有没有简单的方法来删除约束的“依赖性”?

提前致谢

Caius

发表第一条评论后编辑

据我了解,DeleteRule基本上有两种,NoneCascade,各有其含义:

我想做的是显示一条“警告”消息,如下所示:

回答“是”会导致 所有 个元组被删除。
回答“否”会导致 none 个元组被删除。

归结为这个(错误的)代码:

try
{ 
  dt_Areas.Rows[0].Delete();
}
catch (Exception ex)
{
  if (MessageBox.Show("In order to .... Is that what you want?",
                      "Warning",
                      MessageBoxButton.YesNo) == MessageBoxResult.Yes)
  {
    (ForeignKeyConstraint)(dt_Locations.Constraints[0]).DeleteRule = Rule.Cascade;
    dt_Areas.Rows[0].Delete();
    (ForeignKeyConstraint)(dt_Locations.Constraints[0]).DeleteRule = Rule.None;
  }
}

然而,如前所述,这段代码是错误的,因为似乎无法在运行时更改DeleteRule,特此编译结果:

error CS1061: 'Constraint' does not contain a definition for 'DeleteRule' 
and no accessible extension method 'DeleteRule' accepting
a first argument of type 'Constraint' could be found
(are you missing a using directive or an assembly reference?)

我该如何解决这个问题?

应该可以通过例如

在运行时切换约束的行为
    ((ForeignKeyConstraint)dt_Locations.Constraints[0]).DeleteRule = Rule.Cascade

如果您的 FK 并不总是第一个约束,您可能需要使用 eg

查找它
foreach(Constraint c in dt_Locations.Constraints)
  if(c is ForeignKeyConstraint fk ...)
    fk.DeleteRule = ....

如果需要,您可以用其他逻辑(例如检查名称)替换三个点..