3

私は、MVC3 アプリケーションで Entity Framework を使用する多くの例を見てきました。それらは、内部に edmx を含む 1 つの mvc3 Web プロジェクトしかない非常に単純なデモです。

そのため、「using」ステートメントを使用して、接続のオープンとクローズのベスト プラクティスを使用できます。

using(var context = new SchoolEntities())
{
    // do some query and return View with result.
}

また、コンテキストがまだ破棄されていないため、「using」ステートメント内で遅延読み込み (ナビゲーション プロパティ) を正しく使用できます。

foreach(var item in student.Course)
{
    // do something with the navigation property Course
}

n 層アプリケーションになるまでは、すべてが完璧に見えます。

DAL、BLL、MVC3 UI を作成しました。

DALには内部に edmx があり、SchoolDA.csのような演算子クラスがあります。

public class StudentDA()
{
    public Student FindStudent(int studentId)
    {
        using(var context = new SchoolContext())
        {
            // do query, return a student object.
        }
    }
}

次に、BLL で次を使用する場合:

var student = studentDa.FindStudent(103);

次に、そのナビゲーション プロパティを呼び出します。

student.Course

エラーが発生します(もちろん):

ObjectContext インスタンスは破棄されており、接続を必要とする操作には使用できなくなりました。

したがって、StudentDA.cs を次のように変更する必要があります。

public class StudentDA() : IDisposable
{
    private SchoolEntites context;

    public StudentDA()
    {
        context = new SchoolEntities();
    }

    public void Dispose()
    {
        context.Dispose();
    }

    public Student FindStudent(int studentId)
    {
        // do query, return a student object.
    }
}

次に、BLL は次のように変更されます。

public Student FindStudent(int id)
{
    using(var studentDa = new StudentDA())
    {
        // this can access navigation properties without error, and close the connection correctly.
        return studentDa.FindStudent(id);
    }
}

Update() メソッドを満たすまで、すべてが再び完璧に見えます。

ここで、BLL.FindStudent() から取得した学生オブジェクトを更新する場合、 context.SaveChanges() は 0 を返します。これは、コンテキストが BLL.FindStudent() で既に破棄されており、何も更新されないためです。データベース。

var optStudent = new StudentBO();
var student = optStudent.FindStudent(103);
student.Name = "NewValue";
optStudent.Update(student);

3 タイヤ アプリケーションで EntityFramework を使用する方法を知っている人はいますか? または、コンテキストを正しく管理するにはどうすればよいですか。Web レイヤーでナビゲーション プロパティを頻繁に使用しますが、サーバー メモリを消費するために常に接続を開いたままにしておくことはできません。

4

2 に答える 2

7

EF コンテキストの有効期間を処理する方法は複数あります。Web アプリでは、通常、コンテキストは HttpRequest に対して一意です。たとえば、これを Web アプリケーションで手動で処理し、Thread/HttpRequest EF コンテキストごとに処理する場合は、次のようにできます ( http://www.west-wind.com/weblog/postsからコピーされたコード)。 /2008/Feb/05/Linq-to-SQL-DataContext-Lifetime-Management ):

internal static class DbContextManager
{
    public static DbContext Current
    {
        get
        {
            var key = "MyDb_" + HttpContext.Current.GetHashCode().ToString("x")
                      + Thread.CurrentContext.ContextID.ToString();
            var context = HttpContext.Current.Items[key] as MyDbContext;

            if (context == null)
            {
                context = new MyDbContext();
                HttpContext.Current.Items[key] = context;
            }
            return context;
        }
    }
}  

そして、簡単に使用できます:

var ctx = DbContextManager.Current

しかし、生涯管理は、AutofacCastle Windsor、またはNinjectなどの IoC フレームワークに任せることをお勧めします。これらは、登録されたオブジェクトの作成/破棄と他の多くの機能を自動的に処理します。

于 2012-08-14T07:10:00.090 に答える