删除后立即将对象重新插入数据库(DbLinq)

时间:2010-01-28 20:33:42

标签: c# mysql linq-to-sql dblinq

我有一个MySql数据库,其总体结构如下:

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

我正在使用InnoDB来允许外键,而指向ProbeDefinition的所有外键都设置了ON DELETE CASCADE

我遇到的问题是当我在代码中删除ProbeDefinition时,会立即重新插入。级联删除正确发生,因此其他表被清除,但似乎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会正确删除,并使用以下日志:

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

编辑:经过进一步测试,似乎只有在我填充了列表ProbeDefinition s的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()

1 个答案:

答案 0 :(得分:1)

当您的对象有多个引用时,会出现问题。通过DbLinq源代码,我了解到在DELETE完成后,它会逐步浏览所有其他“监视”对象,寻找参考。

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

无论哪种方式,在我的情况下,解决方案是仅使用单个方法访问表,使用该方法删除,或使用两种方法删除。为了让它正常工作,我使用了第二种方法:

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

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