10


0

XMLデータベースフィールドを使ったLINQ-to-SQL - なぜこれが機能するのですか

いくつかの背景:私はC#アプリケーションを介して更新するためにlinq-to-sqlを使用したいデータベースを持っています。 この表の列の1つにXMLデータ型があります。

そのテーブルの他のすべての列(XMLデータ型ではない)は完全に更新されますが、XMLフィールドに変更を加えると、プログラムは(一見)正しく実行されますが、フィールドは常に元の値を保持します`+ SubmitChanges()+`を実行します。

私はインターネットを見回し、同様の問題を診断しているMicrosoft Connectについてのいくつかの投稿を見つけ、そしてついに解決策https://connect.microsoft.com/VisualStudio/feedback/Workaround.aspx?FeedbackID=360433 [ここ]:

XMLフィールドを強制的に更新しても、これはうまくいきません。

XElement tmp = MyLinqObject.XmlField;
MyLinqObject.XmlField = null;
MyLinqObject.XmlField = tmp;

その代わりに、LINQにXML列の更新を強制してクローンオブジェクトを割り当てます。

MyLinqObject.XmlField = new XElement (MyLinqObject.XmlField);

私はこれが確かにうまくいくように見えることを確認することができます、しかし私は正確に理由がわかりません。 私の唯一の推測は、XmlFieldプロパティがヒープ上にある種のユニークな識別子を持っていて、クローンを作ることによってそれに新しいユニークな識別子を割り当てたということです。 それからLinqがクエリを生成するとき、それはフィールドが更新されたかどうか確かめることさえ試みません、それは新しいidを持っているので、それは単にデータベースに値を書くだけです。 しかし、私は単に推測していて、他の誰かが舞台裏で起こっていることのより良い理解を提供できることを願っています。

編集:Jonの投稿に対処するために(MS Connectサイトで説明されているように)この問題の理由は、 "Linq-to-SQLはXElement.Changedイベントを処理しないためXMLフィールドは更新されない"です。

私の実装では、機能するコードは次のようになります。

MyXElementProperty.SetElementValue("Author", author);

MyXElementProperty = new XElement(MyXElementProperty);

参考のために(この質問を見つけた人への参照)、次のものも機能します。

MyXElementProperty = new XElement(MyXElementProperty);

MyXElementProperty.SetElementValue("Author", author);

2 Answer


10


新しい `+ XElement +`にすると、別のオブジェクトが作成されます。 「古さ」を検出するためには参照均等性を使用している可能性があります。これは明らかにこれを新しい値として扱うことになります。

実際にどの時点で要素に変更を加えていますか。 LINQ to SQLで元の値のキャッシュコピーを作成し、それを新しい値と比較します。 参照を単にコピーすることによってその「キャッシュコピー」を取っている場合、そのオブジェクトに対して何をしても、2つは等しいと常に考えられます。 代わりに_new_要素を作成してから_that_を変更しても、古いオブジェクトには古い値が残っているので、比較によって、変更が加えられたことがわかります。 それは理にかなっていますか?


0


これは非常に「異なる」回避策でした。データベースのXMLフィールドがアップロードされていない理由を突き止めようとしました。 新しいXElement(updatedXElement)も私のために働きました!