2017-12-08 18 views
0

私は、(別個のリポジトリを作成するのではなく).net MVC Unit of Work APIを実装しようとしていましたが、それは正しくはありません。私はこれについて正しい方法で行っていますか?この周りEntity Frameworkとリポジトリなしで簡単な作業単位を作成する

BaseController

public class BaseController : ApiController 
    { 
     protected DBEntities _dbEntities; 

     protected override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      _dbEntities = new DBEntities(); 
     } 

     protected override void OnActionExecuted(ActionExecutedContext filterContext) 
     { 
      _dbEntities.SaveChanges(); 
     } 
    } 

MyController

public class MyController : BaseController 
{ 
    public HttpResponseMessage PutMyObject(int id, int id2) 
    { 
     if (id != 0) 
     { 
      var myObject = _dbEntities.MyObjects.Where(x => x.id == id); 
      if (myObject.Count() > 0) 
      { 
       MyObject temp = myObject.SingleOrDefault(); 
       temp.Processed = true; 
       return Request.CreateResponse(HttpStatusCode.OK); 
      } 
      else 
      { 
       return Request.CreateErrorResponse(HttpStatusCode.NotFound); 
      } 
     } 
     else 
     { 
      /* do some other stuff */ 
     } 
    }    

} 

私の思考は、コントローラのアクションは、単一の作業単位であるということです。コントローラのアクションが開始されるとデータベース接続が開き、応答が返されるとSaveChangesが呼び出されます。

私は正しい方法でこれについてお伝えしますか? savechangesがBaseController内で呼び出された後、_dbentitiesを処分する必要がありますか? (またはこれはコードレビュー交換のためのより良い質問です)

+0

Spring/HibernateがJavaの世界でどのように動作するかはあまり変わりません。個人的には私はあまり熱心ではありませんが、あなた自身のアプリケーションのために十分に機能することがわかります。 –

+0

これは[CodeReview.SE](https://codereview.stackexchange.com/)に適していると思います。私があなたの設定で見る唯一の実際の問題は、(a)コードを複製することなくMVCバックエンドを呼び出す以外の方法でデータにアクセスすることができないことです。(b) SaveChanges() '、例えばあなたが何かを保存してエラーを返すことを望まない中間的な方法を決めるとき。しかし、これは、例えば、 'SaveChanges()'が呼び出されないようにするブール型変数を持っています。 – Flater

+0

'filterContext'で渡されたExceptionプロパティは、エラー状態を処理するために例外を使用しているかどうかを確認できます。 –

答えて

0

私は、OOPアーキテクチャと柔軟性のためには悪い設計だと思います。なぜなら、主なMVCプロジェクトではデータベースアクションを提供しなければならず、他の層にそれらを提供できないからです。したがって、リポジトリパターンを提供する必要があります。メインMVCプロジェクトやその他の必要なプロジェクトからリポジトリにアクセスする必要があります。ですから、スレッドごとにシングルトンクラスの_dbEntitiesオブジェクトを処理することをお勧めします。

サンプルシングルトンクラスはこのようになります。

public class UnitOfWorkSampleContextBase : IDisposable 
{ 
    [ThreadStatic] 
    private static UnitOfWorkSampleContextBase _instance; 

    public static UnitOfWorkSampleContextBase Instance 
    { 
     get 
     { 
      if (_instance == null) 
      { 
       _instance = new UnitOfWorkSampleContextBase(); 
      } 
      return _instance; 
     } 
    } 

    public SampleDbContext Context { get; private set; } 

    private UnitOfWorkSampleContextBase() 
    { 

    } 

    public void Commit() 
    { 
     Context.SaveChanges(); 
    } 

    public void ResolveContext() 
    { 
     Context = new SampleDbContext(ConfigurationManager.ConnectionStrings["MainDatabase"].ConnectionString); 
    } 

    public void Dispose() 
    { 
     Context.Dispose(); 
     Context = null; 
    } 
} 

このようにDbContextを作成できます。

UnitOfWorkSampleContextBase.Instance.ResolveContext(); 

次に、このようなコンテキストでアクションを実行できます。

var context = UnitOfWorkSampleContextBase.Instance.Context; 
var records = context.sampleEntities.ToList(); 

最後に、このようなコンテキストをコミットして破棄することができます。

UnitOfWorkSampleContextBase.Instance.Commit(); 
UnitOfWorkSampleContextBase.Instance.Dispose(); 

シングルトンクラスは、必要なリポジトリクラスにアクセスするために、リポジトリ層またはベース層にある必要があります。

注:CastleWindsorなどを使用している場合は、 を作成してコンテキストをコミットする方が、インターセプタのほうがよいでしょう。また、スレッドごとにシングルトンコンテキストクラスを初期化することが非常に重要です。

関連する問題