2015-10-20 8 views
8

当社のアプリケーションでEntity Frameworkを数年間使用しても、当社はユーザーにラップトップの導入を開始しています。ラップトップはオンサイトで使用されており、ネットワークに直接接続されています。例外は私の理論は問題がラップトップは、パソコンとは異なり、行くという事実から生じるということであるコンテキストを破棄せずにEntity Framework接続を更新するには

System.Data.SqlClient.SqlException: A transport-level error has occurred when receiving results from the server. 
(provider: Session Provider, error: 19 - Physical connection is not usable) 

を示すログに記録して以来、我々は、我々のプログラム内でのクラッシュの巨大な増加を見てきました

寝るため。私は、ノートパソコンがスリープ状態になったときにネットワークアダプタが無効になっていると思って、復帰時に再び有効にします。私たちのプログラムは、もはや存在しない接続を使ってサーバと通信しようとしていると思います。私はそれが目覚めたときに検出し、接続をリフレッシュすることができ

Microsoft.Win32.SystemEvents.PowerModeChanged 

だから、私のアイデアはに対応するためでした。問題は、これを行うように見える唯一の方法は、現在のDbContextを破棄して新しいインスタンスをインスタンス化することです。

この問題は、コミットされていない変更がすべて失われるという問題があります。ユーザーがレコードを更新して終日働いていると、仕事を失うことになります。それだけでなく、私たちはすべてのアプリケーションとビューモデルのすべてを調べ、通知付きの編集モードから何らかのキックをユーザに組み込む必要があります。全く綺麗ではありません。

私が持っていたもう1つのアイデアは、DbContextを複製するメソッドを作成することでした。コンピュータが目を覚ますと、新しいDbContextを作成し、それを破棄する前に古いDbContextをコピーすることができます...しかし、私たちのデータモデルの中には大規模なものがあり、それぞれのために深いクローンメソッドを作成するのはかなり手掛かりになります。

これはまだ私たちが行かなければならない方法かもしれないが、現状を失うことなくEntity Framework DbContextの接続をリフレッシュする方法を誰かが知っているかどうかをチェックするのは馬鹿だ。状態。

誰もが持っている可能性のあるアドバイスに感謝します。

+2

あなたはどのようなデザインをしているのか分かりませんが、メモリに保存されていない大きな情報を保存することはお勧めできません。何とか定期的に情報を自動保存する必要があります。少なくともそれがあれば、損失情報ができるだけ最小限に抑えられます。多くのアプリケーション(Webアプリケーションを含む)はこの戦略を使用します。 –

+0

それは公正な点です。私たちが自動保存しない理由は、ユーザーが変更を保存するかキャンセルするかを決定できるためです。これには2つの戦略があります.1)編集開始時に元のデータのコピーをメモリに作成し、データが変更されたときにデータベースへのライブアップデートを維持します。 2)作業コピーをメモリに保存し、ユーザーが変更を保存するときにのみデータベースに保存します。実装の観点から、第2のオプションはより簡単で、私たちが使用する方法です。それは、上に見られるような問題につながると言いました。 – Chronicide

+0

ラップトップがスリープ状態になる前に発生するイベントはありませんか?あらかじめ保存しておいて、接続を閉じて、目を覚ますだけでもう一度開くことができます。 – Matt

答えて

0

私はちょうどコメントしていましたが、それを行うのに十分な評判のポイントがありません。とにかく、Entity Frameworkとの接続が解除された状態で作業できないのかどうか疑問に思いましたか?下記のリンクにあるかもしれない記事を助けることができる:

https://msdn.microsoft.com/en-us/data/jj592676.aspx

+0

参考になりました。残念ながら、デッド接続を使用して通信しようとしているEntity Frameworkの問題は解決されません。それは、コンテキストにエンティティを取り付ける方法に関する明確な記事です。新しいエントリを作成するのではなく、クローンメソッドを作成する必要がある場合は非常に役立ちます。既存のエントリを追加するか、私の古い状況から変更されました。それは少し実験をするだろうが、それはまだ非常に良いリソースです。ありがとうございました。 – Chronicide

3

私はそれはあなたの特定のケースに役立つかどうか、わからないんだけど、あなたはDbConetxtクラスで使用する接続の状態を確認し、最終的にすることができますそれを再び開きます。

if(context.Database.Connection.State == ConnectionState.Closed) { 
    context.Database.Connection.Open(); 
} 

それそれのコンストラクタでDbContextへの接続を渡し、手動で接続を管理することも可能。

var conn = new SqlConnection("{connectionString}")); 
var context = new DbContext(conn, contextOwnsConnection: false); 

... 

if(conn.State == ConnectionState.Closed) { 
    conn.Open(); 
} 
context.SaveChanges(); 

... 

context.Dispose(); 
conn.Dispose(); 

このコードをEF 5以前のバージョンで使用する場合は、いくつかの制限があります。 official documentation.

関連する問題