2017-02-01 7 views
0

が配置されてきた私は、私はリストC#Entity FrameworkのObjectContextはインスタンスが

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. 

を反復処理したいとき、私は次のコード

 private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e) 
     { 
      int id = int.Parse(dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString()); 
      Aufenthalt a; 
      using (var db = new GastContext()) 
      { 
       a = db.Aufenthalte.First(x => x.AufenthaltID == id); 
      } 

      Aufenthaltsform frm = new Aufenthaltsform(currentGast, a); 
      frm.ShowDialog(); 
     } 

でフォームを開き、これは次のエラーを取得します私のフォームのコンストラクタと私のアプリケーションは上記のエラーをスローする

public Aufenthaltsform(Gast g, Aufenthalt a) 
    { 
     InitializeComponent(); 

     MessageBox.Show(a.Mitreisende.Count.ToString()); 
    } 

これはAufenthaltオブジェクトですMitreisendeGast - あなたのAufenthalt

public class Aufenthalt 
    { 
     public int AufenthaltID { get; set; } 
     public DateTime Anreisedatum { get; set; } 
     public DateTime Abreisedatum { get; set; } 

     public virtual List<Mitreisender> Mitreisende { get; set; } 

     public virtual Gast Gast { get; set; } 

     public Aufenthalt() 
     { 
      Mitreisende = new List<Mitreisender>(); 
     } 
    } 
+0

http://stackoverflow.com/questions/40729137/why-are-外部キーインファーコード - 最初にマークされた仮想/ 40729675#40729675これがなぜ起こるのかに関する少しの理論を持つためにこれを見てください –

答えて

2

は、2つのナビゲーション性を有しています。レイジーローディングを使用している場合は、未処理のDbContextが必要です。

Aufenthalt a; 
using (var db = new GastContext()) 
{ 
    a = db.Aufenthalte.First(x => x.AufenthaltID == id); 
} 

// db is disposed here 
Aufenthaltsform frm = new Aufenthaltsform(currentGast, a); 

次のことができます:

  • 代わりに遅延読み込みの積極的なロードを使用
  • 生きコンテキストを維持するusing文を削除するには、ときusing声明を経由して、コンテキストを配置した後、それらのプロパティを読み取るしようと、エラーを持っている理由です
  • 移動フォームの作成と表示中にusingステートメント
  • get Mitreisende countルートオブジェクトを渡す代わりに番号をフォームに渡し、後でナビゲーションプロパティを使用します。

最初のオプション - DbContextは軽量オブジェクトですので、処分しないでください。

var db = new GastContext(); 
Aufenthalt a = db.Aufenthalte.First(x => x.AufenthaltID == id); 
Aufenthaltsform frm = new Aufenthaltsform(currentGast, a); 

番目のオプション - ではない非常に良いオプションは、あなただけ関連するエンティティの数を必要とするので。なぜそれらをすべてメモリにロードするのですか?しかし、あなたは

Aufenthalt a; 
using (var db = new GastContext()) 
{ 
    a = db.Aufenthalte.Include(x => x.Mitreisende).First(x => x.AufenthaltID == id); 
} 

Aufenthaltsform frm = new Aufenthaltsform(currentGast, a); 

第三の選択肢は

using (var db = new GastContext()) 
{ 
    Aufenthalt a = db.Aufenthalte.First(x => x.AufenthaltID == id); 
    Aufenthaltsform frm = new Aufenthaltsform(currentGast, a); 
    frm.ShowDialog(); 
} 

明らかであることができ、最良のオプションは、必要とされていないデータを形成するために渡していません。コレクション全体ではなく、Mitreisendeの数だけ必要です。

a = db.Aufenthalte.First(x => x.AufenthaltID == id); 
// place this within the disposable context (using) 
int count = a.Mitreisende.Count; 
+0

または使用してください。インクルード –

0

この方法を

public Aufenthaltsform(Gast g, int mitreisendeCount) 
{ 
    InitializeComponent(); 
    MessageBox.Show(mitreisendeCount.ToString()); 
} 

にフォームを変更し、それを呼び出しますまだ読み込まれていないナビゲーションプロパティーMitreisendeを持っています(エンティティフレームワークもまだそのようにしていないことを覚えています)。

あなたがa.Mitreisende.Countを呼び出した瞬間には、Entity FrameworkのはMitreisendeプロパティを埋めるためにしようとしますが、using文がエラーにつながる、DbContextが配置される原因となったので、それはそうすることはできません。

複数の修正があります。

1)は、単にusingブロックを除去することで、DbContextを処分しないでください。 .NETはそれを少し後で削除しますが、これは多くの場合傷つくことはありません。

2)自分でDbContextを破棄しますが、ブロックの後ろではなくブロック内に次の2行を入れて少し遅らせます。

3)Entity Frameworkのは.Includeステートメントを使用して、それを遅らせるのではなく、できるだけ早くMitreisendeをロードしていることを確認してください:

a = db.Aufenthalte.Include(x => x.Mitreisende).First(x => x.AufenthaltID == id); 
0

オブジェクトa自体は次のとおりです。だから、あなたは文脈が配置される前に、クエリが実行されていることを確認する必要があります

int mitreisendeCount; 
using (var db = new GastContext()) 
{ 
    mitreisendeCount = db.Aufenthalte.First(x => x.AufenthaltID == id).Mitreisende.Count; 
} 

Aufenthaltsform frm = new Aufenthaltsform(currentGast, mitreisendeCount); 
関連する問題