0

一般的な構造が次のような MySql データベースがあります。

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

外部キーを許可するために InnoDB を使用してProbeDefinitionいます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ですか? Manufactureraをまったく同じ方法で削除すると、次のログで正しく削除されることに注意してください。

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

編集:さらにテストすると、これは ListBox に のリストを入力した後にのみ発生するようですProbeDefinition

次のスニペットが実行される前後に、上記の削除コードを実行してみました。

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 ソースをDELETEステップ実行すると、a が完了すると、参照を探して他のすべての「監視対象」オブジェクトをステップ実行することがわかりました。

この場合、表database.ProbeDefinitionと製造元の参照を介して複数の参照がありますmanufacturer.ProbeDefinition。両方の方法でオブジェクトにアクセスするまで、これは問題ではありません。を使用するとRemove、製造元から参照を削除できます。 を使用DeleteOnSubmitすると、テーブルからオブジェクトが削除されます。どちらか一方を実行すると、もう一方の参照がまだ存在するため、オブジェクトは再挿入するようにマークされます。これが他の参照を削除しないという DbLinq のバグなのか、それとも予想される動作なのかはわかりません。

いずれにせよ、私の場合、解決策は、単一の方法のみを使用してテーブルにアクセスし、その方法を使用して削除するか、両方の方法を使用して削除することです。それを機能させるために、2番目の方法を使用しました。

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

編集:プロジェクトおよび同様の問題に関するさらなる作業の結果、実装の真の根本的な問題が見つかりました。私は長寿命の DataContext を持っていますが、(SubmitChanges を機能させるための) キャッシュのしくみでは、これを行うことはできません。本当の解決策は、存続期間の短い DataContext を持ち、各メソッドでデータベースに再接続することです。

于 2010-01-29T16:47:14.923 に答える