0

エンティティ フレームワークを使用して、N 層の Wpf アプリケーションでデータを永続化しています。私の dbcontext はすべてのリポジトリ間で共有され、破棄されることはありません。データを永続化するとき、オブジェクトを変更済みとしてマークし、変更を保存しようとします。オブジェクトの永続化中にエラーが発生した場合、オブジェクトは変更済みとしてマークされたままになり、ユーザーが現在の操作を中止すると、別のオブジェクトを保存するときに同じエラーが発生します。

dbcontext で SaveChanges をオーバーライドすることでこれを解決しました。エラーが発生した場合は、すべての変更を受け入れます (以下のコードを参照)。そのため、オブジェクトにエラーが発生し、すべてのオブジェクトが永続化されていなくても、変更されていないとマークされます。

これは正しくありません...この解決策に同意する人はいますか? 別の解決策は、リポジトリの各メソッドで dbcontext を新しくし、すぐに破棄することです。これにより、リポジトリがより複雑で「うるさい」ものになり、データを遅延ロードする機能も失われます... 誰か別の解決策がありますか?

    //In my repositories
    public void UpdateObject(Object object)
    {
        dbContext.Entry(object).State = EntityState.Modified;
        dbContext.SaveChanges();
    }

    //In my dbcontext class
    private ObjectContext ObjectContext()
    {
        return (this as IObjectContextAdapter).ObjectContext;
    }

    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (Exception)
        {
            ObjectContext().AcceptAllChanges();
            throw;
        }
    }
4

2 に答える 2

0

このように長生きするコンテキストを持つことは、良い考えではありません。すべてのエンティティと変更が追跡されると、大きくて遅くなり、並行性に関連する問題が発生する可能性があり、コンテキストによってスローされた例外がアプリケーション全体に影響を与える可能性があります。

http://msdn.microsoft.com/en-us/data/jj729737

別の解決策は、リポジトリの各メソッドで dbcontext を新しくし、すぐに破棄することです。これにより、リポジトリがより複雑で「うるさい」ものになり、データを遅延ロードする機能も失われます

切断されたシナリオでは、各要求/作業単位で作成および破棄します。リポジトリが複雑になることを心配していますか? 次に、この追加の抽象化レイヤーを使用しないでください。リポジトリは本当に必要ですか? DbContext を直接使用することで得られるものは何ですか?

遅延読み込みに関しては、切断された n 層のシナリオでは、遅延読み込みはあまり適切ではないと思います。おそらく、ビューに必要なデータの一括読み込みを使用するか、関連データを取得するために個別のメソッド呼び出しを行う必要があります。

于 2013-04-29T06:53:11.547 に答える
0

私たちのチームは、以下のようなアプローチを使用しています。

リポジトリ:

public class StudentRepository
{
    private readonly MyEntities _context;

    public StudentRepository(MyEntities context)
    {
    _context = context;
    }

    // Basic CRUD methods etc
}

ビジネスの論理:

public AddStudent(Student student)
{
    using( var context = new MyEntities())
    {
        var studentrepo = new StudentRepository(context);
        studentrepo.Add(student);
        context.SaveChanges();
    }
}

これは非常に単純化された例ですが、アイデアが得られるはずです。コードを削減するために、CRUD メソッドのベース ジェネリック リポジトリ クラスも使用します。

作業中のプロジェクトに Web サービスが含まれている場合は、API コントローラーで dbcontext をインスタンス化し、Dispose メソッドをオーバーライドしてそれを取り除きます。

于 2013-04-29T00:19:54.627 に答える