0

EF5に問題があります。MVC 4.5 を使用しています

リクエストごとに1つのコンテキストを「パターン」にしようとしています。

「作業単位」パターンも、テストも DI も使用していません。

Generic Repository パターンを使用して DB とやり取りしています。各リポジトリは、シングルトン「DataContextManager」によって維持される同じコンテキストを使用します。

グローバル asax の各リクエストでコンテキストを更新しますが、何か問題が発生しています。つまり、ページ化されたリストがあり、DB のデータを手動で変更するとページごとに移動すると、正しく更新されません。これは HTML キャッシュの問題ではありません。テストしました。

私は「このようなもの」を持っているので、EFコンテキストの問題であることを知っています:

private static Context C; //for the singleton. And in global.asax

public Application_BeginRequest()
{    
    DataContextManager.RefreshNew();
}

protected void Application_EndRequest(object sender, EventArgs e)
{
    Domain.DataContextManager.Dispose();
}

そして、リストが初めて機能し、2番目のページでコンテキストが破棄されたというエラーが表示されます。

静的変数でコンテキストを使用することについて何か読んだことがありますが、何が起こっているのかわかりません。UnitOfWork パターンを実装するには、多くのコードを変更する必要があるため、このような単純なものを使用したいと思います。

これが私のクラスの小さなスニペットです:

 public class DataContextManager
    {
        private static Entities _Context;

        private const string ConnectionString = "connString";

        public static Entities Context
        {
            get
            {
                if (DataContextManager._Context == null)
                    DataContextManager._Context = new Entities(ConfigurationManager.ConnectionStrings[ConnectionString].ConnectionString);

                return DataContextManager._Context;
            }
        }

        //This method is not necessary but made it for testing
        public static void RefreshNew()
        {                
            DataContextManager._Context = new Entities(ConfigurationManager.ConnectionStrings[ConnectionString].ConnectionString);
        }

        public static void Dispose()
        {
            if (DataContextManager._Context != null)
            {   
                DataContextManager._Context.Dispose();
                DataContextManager._Context = null;
            }
        }
    }

また、リポジトリは DataContextManager を次のように使用します。

public class BaseRepository<TEntity> where TEntity : class
    {
        internal Entities context;
        internal DbSet<TEntity> dbSet;

        public BaseRepository()
            : this(DataContextManager.Context)
        {
        }

        public BaseRepository(Entities context)
        {
            this.context = context;
            this.dbSet = context.Set<TEntity>();
        }

前もって感謝します!

パブロ。

4

1 に答える 1

0

DbContextすべてがプロパティにアクセスするだけのように見えるため、マネージャークラスが本当に必要かどうかはわかりません。

そうは言っても、通常DbContextは静的クラスでの使用を避ける必要があります。それを裏付ける標準的な情報源はありませんが、私の個人的な経験では、ある時点で静的クラスが提供する利点よりも多くの問題を引き起こすということです。したがって、マネージャーを次のように更新します。

public class DataContextManager
{
    private readonly string connectionToUse = string.Empty;

    private Entities _context;

    public Entities Context
    {
        get
        {
            if (_context == null)
            {
                _context = new Entities(WebConfigurationManager.ConnectionStrings[connectionToUse].ConnectionString);
            }

            return _context;
        }
    }

    public DataContextManager()
    {
        connectionToUse = "connString";
    }

    public DataContextManager(string key)
    {
        connectionToUse = key;
    }


    #region IDisposable Members

    public void Dispose()
    {
        this.Dispose(true);

        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposeAll)
    {
        if (disposeAll)
        {
            _context.Dispose();
        }
        _context = null;
    }

    #endregion
}

次に、保護されたフィールドを各コントローラーに追加し、コントローラーのコンストラクターでマネージャーをインスタンス化します。

protected DataContextManager Manager = null;

public HomeController()
{
    Manager = new DataContextManager();

    // or
    //
    //__manager = new DataContextManager("connection-To-Use");
}

すべてのコントローラーが同じクラスを使用している場合は、継承DbContextするクラスを作成してマネージャーをそのクラスに移動することで、重複を避けることができます。BaseControllerSystem.Web.Mvc.Controller

于 2014-01-10T01:22:36.363 に答える