1. Should i close it after every query?
.Net がそれを行うので、それを処理させます。これはガベージ コレクターのタスクです。したがって、オブジェクトを手動で破棄しないでください。これは、Jon Skeet による良い回答です: https://stackoverflow.com/a/1998600/544283。ただし、using(IDisposable){ }
ステートメントを使用して、GC にその作業を強制することができます。リソースの再割り当てに関する素晴らしい記事があります: http://www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About。
2. A connection in static class is good?
データ コンテキストを静的にしないでください。データ コンテキストは、スレッド セーフでもコンカレント セーフでもありません。
3. Is there a good design pattern for this problem?
Belogix が言及したように、依存性注入と作業単位パターンは優れています。実際、エンティティ フレームワークは作業単位そのものです。DI と UoW は少し過大評価されていますが、IoC コンテナーを初めて扱う場合は実装が容易ではありません。その道を進む場合は、Ninject をお勧めします。もう 1 つは、テストを実行しない場合、DI は本当に必要ないということです。これらのパターンの素晴らしい点は分離することです。そのため、汗をかかずにテストとモックを行うことができます。
要するに: コードに対してテストを実行する場合は、これらのパターンを使用してください。そうでない場合は、必要なサービス間でデータ コンテキストを共有する方法の例を提供します。これが 4 番目の質問に対する答えです。
4. What is the best method for making database connection (static, per request)?
コンテキスト サービス:
public class FooContextService {
private readonly FooContext _ctx;
public FooContext Context { get { return _ctx; } }
public FooContextService() {
_ctx = new FooContext();
}
}
他のサービス:
public class UnicornService {
private readonly FooContext _ctx;
public UnicornService(FooContextService contextService) {
if (contextService == null)
throw new ArgumentNullException("contextService");
_ctx = contextService.Context;
}
public ICollection<Unicorn> GetList() {
return _ctx.Unicorns.ToList();
}
}
public class DragonService {
private readonly FooContext _ctx;
public DragonService(FooContextService contextService) {
if (contextService == null)
throw new ArgumentNullException("contextService");
_ctx = contextService.Context;
}
public ICollection<Dragon> GetList() {
return _ctx.Dragons.ToList();
}
}
コントローラ:
public class FantasyController : Controller {
private readonly FooContextService _contextService = new FooContextService();
private readonly UnicornService _unicornService;
private readonly DragonService _dragonService;
public FantasyController() {
_unicornService = new UnicornService(_contextService);
_dragonService = new DragonService(_contextService);
}
// Controller actions
}
再考 (ほぼ編集): エンティティのプロキシを作成しないようにコンテキストが必要なため、遅延読み込みも必要ない場合は、次のようにコンテキスト サービスをオーバーロードできます。
public class FooContextService {
private readonly FooContext _ctx;
public FooContext Context { get { return _ctx; } }
public FooContextService() : this(true) { }
public FooContextService(bool proxyCreationEnabled) {
_ctx = new FooContext();
_ctx.Configuration.ProxyCreationEnabled = proxyCreationEnabled;
}
}
ノート:
- プロキシの作成を false に設定すると、すぐに遅延読み込みが行われなくなります。
- API コントローラーを使用している場合、本格的なオブジェクト グラフを処理したくありません。
編集:
最初にいくつか読んでください:
これを成し遂げる:
(_context as IObjectContextAdapter).ObjectContext.Connection.Open();
これは、接続とトランザクションの管理に関するすばらしい記事です。
エンティティ フレームワークは、Connection プロパティを通じて EntityConnection を公開します。読み方: public sealed class EntityConnection : DbConnection
.
接続の管理に関する考慮事項: (前のリンクから取得)
- 操作の前に接続がまだ開かれていない場合、オブジェクト コンテキストは接続を開きます。操作中にオブジェクト コンテキストが接続を開くと、操作が完了すると常に接続が閉じられます。
- 接続を手動で開いた場合、オブジェクト コンテキストは接続を閉じません。CloseまたはDisposeを呼び出すと、接続が閉じます。
- オブジェクト コンテキストが接続を作成する場合、コンテキストが破棄されると、接続は常に破棄されます。
- 実行時間の長いオブジェクト コンテキストでは、不要になったときにコンテキストを確実に破棄する必要があります。
それが役に立てば幸い。