1

状況:私がやりたいのは、ページのライフサイクルのデータコンテキストにアクセスできることです。これは主に、(a)一連のusing()を回避し、(b)遅延ロードされたプロパティにアクセスしたときにビュー内のスコープ外の例外を回避するためです。

編集:MVC4とEntityFramework 4.3.1(最新)を使用しています

私が通常することは

using (MyDB b = new MyDB()) {
 ...do all my stuff
}

私のコントローラーまたはデータレイヤーで。私の読書によると、これの良いところは、クリーンで、メモリリークなどが発生しないことです。しかし、欠点は、1ページのライフサイクルでも、これを何度も繰り返すことになり、オブジェクトのコンテキストが失われることです。私はすでにコンテキストを破棄したので表示します。

私はいくつかの読書をして、2009年から同様の投稿を見つけましたが、答えにコードがありません。確かに他の何人かはこれを解決する方法を理解しています-私は何かをしなければならないと思います

Application_BeginRequest and EndRequest

しかし、その方法と、落とし穴/ベストプラクティスが何であるかはわかりません。

あなたの助けに感謝します(可能であればいくつかのコードサンプルで!)

4

4 に答える 4

2

I see you have a tag for asp.net MVC so I assume that is what you're using.

You should be implementing a repository approach like http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

Anyways, all you really need to do is something like this on each of your controllers

private MyDB b = null;
public MyController()
{
      b = new MyDB();
}

protected override void Dispose(bool disposing)
{
      b.Dispose();
      base.Dispose(disposing);
}
于 2012-04-21T16:47:35.380 に答える
1

The way you wish to use your datacontext is absolutely a no-no (unless you are handling a couple of hundred lines database, in which case why EF at all).

But if you have a real production sized database, pinning the context to application scope will result in the following:

  • Since you are mentioning to use lazyload ( a feature I would totally switch of on the server side) sooner or later all you database will be slurped into memory (the context level entity cache)
  • your entity instances will be shared among requests and threads (yes, for write operations true)
  • EntitySet/DbSet is all but threadsafe
  • your write operations will be totally slow and unpredictable as you'll wont be able to save "just your changes" you'll save everything that changed since the last save/submitChanges, and you'll probably save someone other threads half baked entities too

The EF context is IDisposable with a very good reason: it is expected to be used in compact, short operations, and yes: you are supposed to do the using(...) "thing" all the time.

All the above is only a concern if you are building a website, intranet soluton, etc that will be used by more then one person.

于 2012-04-21T17:00:26.477 に答える
1

First don't use lazy loading (Entity Framework goes to the database and brings the results back one row at a time) in the views as queries from the views are bad practice and result in Select N+1 (Select N + 1 is a data access anti-pattern where the database is accessed in a suboptimal way.) or similar bad practices.

Using more than one object context means using more than one database connection per request, resulting in additional strain on the database and slower overall performance also each object context is not aware of the entities that are tracked by the other object context and might have to query the database again for its current state or have to issue an unnecessary update

When writing views, you shouldn't be bothered with thinking about persistence, or the number of queries that you views are generating.

Summary:

  1. Perform all your queries in the action.

  2. Force an eager load of the collection using the Include method to specify what pieces of the object model you want to include in the initial query.

  3. Use one object context per request.

Regards

于 2012-04-21T18:01:39.060 に答える
0

you can return before you exit the using block so the context will be in scope when lazy loading in the view

using (MyDB b = new MyDB()) {
 ...do all my stuff

  return View(b.Data);
}
于 2012-04-21T23:36:32.813 に答える