2011-01-26 11 views
2

asp.net c#Webアプリケーションのlinq to sqlを使用してDataContextに問題があります。外部キーフィールドを更新する前にDataContextが破棄されました

私はDataContextを処分しなかったので例外がスローされていましたが、これはthis questionと同じエラーです。私は静的なDataContextを使用していました。なぜなら、おそらくそれが適切に処理されなかったからです。そして、thisと他のいくつかの記事を読んだ後、彼らは処分されることを確実にするためにステートメントを使用しています。

しかし、DataContextがすでに破棄されているため、外部キーを更新する必要があるときに問題が発生しました。私はなぜそれがすでに処分されているのかわからないし、このシナリオではベストプラクティスが何をするのだろうかなんて、どんなアイデアも大いに評価されるだろう!

ここ

ショート例:

UPDATE:私は私がここに長いのです可能な限り短くすることを試みたときに私の例では、あまりにも混乱だったと思うし、うまくいけば、より良い例:

private static void SendTexts(List<TextAlert> TextQueue) 
{ 
    using (THTDataContext db = new THTDataContext()) 
    { 
     foreach (TextAlert text in TextQueue) 
     { 
      try 
      { 
       // do IntelliSMS stuff 

       // set status to 'sent' 
       text.Status = 1; 

       db.SubmitChanges(); 
      } 
      catch (IntelliSMSException ex) 
      { 
       // set status to 'failed' 
       text.Status = 2; 

       db.SubmitChanges(); 
      } 
     } 
    } 
} 

感謝、

Annelie

+1

私はいつも2番の数字が本当に意味するものは何か、と思っています! ;)真剣にしかし、魔法の数字は、その日を見ている、 "enum"は(他の何も読みやすさの面で)より効果的だろう。そして、 'Status'が' enum'型/ valuesの場合、そういう値を割り当てるのではなく、適切な型を使うことをお勧めします。オフトピック、私は知っているが、私はそれがまともな情報だと思う。 –

+0

@Mr。失望 - 早い選択肢をとるのではなく、まず始めにそれをやっていたはずなのに、今の年齢のリストに載っています。 :) – annelie

+0

あなたのコードスニペットから実際に何をしているのかを推測するのは非常に難しいです:Linq2SQLによって作成されたDBレコードを "MyThing"していて、ステータスは外部キーフィールドですか? – Christoph

答えて

3

おそらく、新しい文脈に入ってくるMyThingを添付する必要があります。このような何かがうまくいくかもしれない:

private static void DoMyStuff(MyThing thing) 
{ 
    using (MyDataContext db = new MyDataContext()) 
    { 
     db.MyThings.Attach(thing); 
     thing.Status = 1; 
     db.SubmitChanges(); 
    } 
} 

それが取り付けられていたら、コンテキストはそれへの変更を追跡し、提出に、それらを格納することができるはずです。

"既に廃棄されている"例外が解決されない場合は、古いコンテキストを破棄する前に"detaching"MyThingを試してみてください。ただし、このルートに移動する必要がある場合は、DataContextのライフサイクルが間違っている可能性があります。エンティティは、同じアプリドメイン内のコンテキスト間を移動するように設計されていないためです。

MSDNのDinesh Kulkarniは、アタッチ/デタッチのビジネスをより理解したいと思っている方はshort blog postです。

+0

「新しいData Contextから読み込まれていない、新しいものではないエンティティのアタッチまたは追加が試行されましたが、これはサポートされていません」というメッセージが表示されますが、私はそれを少し良く理解しています。ありがとう! – annelie

+2

@annelie:おそらくライフサイクルの問題です。リンクはちょっと役立つはずですが、結論はあなたが最初のコンテキストの範囲を広げて、そのスコープの中で 'DoMyStuff'ができるようにする必要があるでしょう。典型的なパターンは、HTTPコンテキスト(Webアプリケーションの場合)またはスレッドローカルストレージ(Webアプリケーションでない場合)にDataContextを格納することです。がんばろう! – ladenedge

+0

ちょうどそれをし、今それは治療を働く!テキストキューを取得してそれらを送信し、参照を渡すために呼び出しの周りを使用してラップしたが、なぜ私はそれを開始しなかったのか分からないが、私は3つの13時間と私の脳この締め切り前にバグを修正することはできません。 ;) どうもありがとうございます! – annelie

3

む〜!データベース内のエントリを更新しようとしているときに例外がスローされた場合、データベース内のエントリを更新しようとすると、例外ハンドラ内では本当に良い考えだと思いますか?

ここで何が起こっているのか、thingの原因は何ですか? MyDataContextの別のインスタンスで実行されたクエリから来たのでしょうか?もしそうなら、それはあなたの問題です。

+0

私は可能な限り短い例を作った、実際には私が(テキストメッセージを送信しようとしている)IntelliSMSExceptionだ、データベースの例外は他の場所で処理されます。このようにするのはまだ悪い考えですか?そして、うん、物のソースは別のインスタンスで実際に実行されました。 – annelie

+1

+1はsubmit-catch-submitを指摘します。あなたがいて、特定の例外タイプをターゲットにしていた場合、その正確な型( 'IntelliSMSException')の' catch'を書くか、 'try'ブロックを投げているコードの周りにだけラップします。これを済ませたら、DBエラーを別々に処理する必要があります。 –

+0

@annelie:それが問題です。前のインスタンスから 'myThing'を切り離し、それを新しいインスタンスにアタッチする必要があります。 – jason

関連する問題