0

我有一个 MySql 数据库,其一般结构如下所示:

Manufacturer <== ProbeDefinition <== ImagingSettings
  ElementSettings  ====^ ^==== ProbeInstance

我正在使用 InnoDB 来允许外键,并且所有指向 a 的外键ProbeDefinition都有 set ON DELETE CASCADE

我遇到的问题是,当我ProbeDefinition在代码中删除 a 时,它会立即重新插入。级联删除正确发生,因此其他表被清除,但似乎 LINQ to SQL 可能无缘无故地发送插入。检查数据库上的 ChangeSet 属性显示 1 个删除,并且没有插入。

我正在使用以下一小段代码来执行删除:

database.ProbeDefinition.DeleteOnSubmit(probe);
database.SubmitChanges();

MySql 中的日志显示运行时正在执行的以下命令:

BEGIN
use `wetscoprobes`; DELETE FROM wetscoprobes.probedefinition WHERE ID = 10
use `wetscoprobes`; INSERT INTO wetscoprobes.probedefinition (CenterFrequency, Elements, ID, IsPhased, ManufacturerID, Name, Pitch, Radius, ReverseElements) VALUES (9500000, 128, 10, 1, 6, 'Super Probe 2', 300, 0, 1) 
COMMIT /* xid=2424 */

什么可能导致这种不必要的INSERT?请注意,Manufacturer以完全相同的方式删除 a 会正确删除,并带有以下日志:

BEGIN 
use `wetscoprobes`; DELETE FROM wetscoprobes.manufacturer WHERE ID = 9 
COMMIT /* xid=2668 */ 

编辑:经过进一步测试,这似乎只发生在我用ProbeDefinitions 列表填充 ListBox 之后。

我尝试在运行以下代码段之前和之后运行上述删除代码:

var manufacturer = (Manufacturer)cbxManufacturer.SelectedItem;
var probes = manufacturer.ProbeDefinition;

foreach (var probe in probes)
{
    cbxProbeModel.Items.Add(probe);
}

该对象在所述代码运行之前被正确删除,但在此之后的任何时间,它都会在删除之后执行插入。它不喜欢对象在某处被引用的事实吗?

这是我正在运行以测试从中间窗口中删除定义的代码:

database.ProbeDefinition.DeleteOnSubmit(database.ProbeDefinition.Last())
database.SubmitChanges()
4

1 回答 1

1

事实证明,当您的对象有多个引用时会出现问题。通过 DbLinq 源代码,我了解到在 aDELETE完成后,它会逐步遍历所有其他“监视”对象,寻找引用。

在这种情况下,我通过表格database.ProbeDefinition和制造商参考有多个参考,manufacturer.ProbeDefinition. 在我通过这两种方法访问对象之前,这不是问题。使用Remove可以删除制造商的引用,使用DeleteOnSubmit将删除表中的对象。如果我做一个或另一个,另一个引用仍然存在,因此该对象被标记为重新插入。我不确定这是否是 DbLinq 中的一个错误,它不会删除其他引用或预期的行为。

无论哪种方式,就我而言,解决方案是仅使用一种方法访问表,然后使用该方法进行删除,或者使用两种方法进行删除。为了让它工作,我使用了第二种方法:

// Delete probe
this.manufacturer.ProbeDefinition.Remove(probe);
database.ProbeDefinition.DeleteOnSubmit(probe);
database.SubmitChanges();

编辑:在项目和类似问题的进一步工作中,我发现了我实施的真正根本问题。我有一个长期存在的 DataContext,以及缓存的工作方式(使 SubmitChanges 工作),你不能这样做。真正的解决方案是拥有一个短暂的 DataContext,并在每个方法中重新连接到数据库。

于 2010-01-29T16:47:14.923 回答