2012-02-14 1 views
2

エンティティデータベースコンテキストを取得する静的クラスを作成することをお勧めします。EF 4.0では、dbcontextを取得する静的クラスは良い方法ですか?

このGetEntity()は、コンテキストを返します。 GetEntityメソッドでは、私は動的接続を持っています。 ログインページに行くと、データベース番号+ユーザ名+パスワードを入力する必要があります。私はSession["DBName"]にdbnameを保管しています。

public static class EntityFactory 
    { 
     public static DBEntities GetEntity() 
     { 
      var scsb = new SqlConnectionStringBuilder(); 

      scsb.DataSource = ConfigurationManager.AppSettings["DataSource"]; 

      scsb.InitialCatalog = "db1"; 
      scsb.MultipleActiveResultSets = true; 
      scsb.IntegratedSecurity = true; 
      if (HttpContext.Current.Session["DBName"] == null) 
      { 
       HttpContext.Current.Response.Redirect("/Account/Step1"); 
      } 
      else 
      { 
       scsb.InitialCatalog = HttpContext.Current.Session["DBName"].ToString(); 
      } 

      var builder = new EntityConnectionStringBuilder(); 

      builder.Metadata = "res://*/nms.bin.Models.DBModel.csdl|res://*/nms.bin.Models.DBModel.ssdl|res://*/nms.bin.Models.DBModel.msl"; 
      builder.Provider = "System.Data.SqlClient"; 
      builder.ProviderConnectionString = scsb.ConnectionString; 
      DBEntities db = new DBEntities(builder.ConnectionString); 
      return db; 
     } 

私はのcontrolerの例でDBContextを取得したい場合は、私はちょうどEntityFactory.GetEntity()を行う必要があり、それは私のDBコンテキストを返します。

  1. それは私がこの
  2. のやり方は、20台のクライアントが同時にしかし異なるdbnameのようにしてログインする場合には問題になる可能性です正しいです。
  3. 現在、私は処分を使用していません、それは問題ですか?私のEntityFactoryクラスに基づいて、自動的に呼び出されるそのクラス内のグローバルディスポーザブルを作成できますか? (私はdescrutorメソッドについて考える)。順番に
+0

@Erangaは編集に大変感謝しています。私の英語は良くありません:) –

答えて

0

  1. あなたは(dbnameは、ユーザ名とパスワードのような)GetEntity()にそれが必要とするすべての情報を渡すことによって、それを改善することができます。今のように、静的メソッドはセッションと緊密に結合されています。メソッドからセッションを移動します。

  2. セッションはユーザー単位ではありません。

  3. DbContextから継承する場合は、オブジェクトを使用した後にDisposeを呼び出すことができます。 ES:dbEntitiesObj.Dispose();

1

staticファクトリメソッドは、ユニットテストのためのモックすることは困難です。だからあなたのコントローラ内のあちこちの例では、あなたが持っていた場合:

public void SomeControllerMethod() 
{ 
    var entities = EntityFactory.GetEntity(); 
    return entities.Something // ... get whatever data... 
} 

そして、あなたはユニットテストで嘲笑データコンテキストを使用する方法?それはやりにくいでしょう。 それは通常、コンストラクタで、あなたのコントローラにあなたの状況を「注入」する方が良いだろう(上のWikipediaの記事を読んで「dependency inversion principal」あなたは概念に精通していない場合)のように、:

public class SomeController 
{ 
    private readonly IDBEntities entities; 

    // db context passed in through constructor, 
    // to decouple the controller from the backing implementation. 
    public void SomeController(IDBEntities entities) 
    { 
     this.entities = entities; 
    } 
} 

そして、コントローラメソッドに参照渡しのものを使用させます。この方法で、依存性注入ツールを使用して適切なdbコンテキストを取得したり、虚偽のコンテキストを渡したりすることができます。

MVC2が依存性注入フレームワークを追加する良い方法を持っていたかどうかはわかりませんが、MVC3はわかります。

あなたのアプローチも基本的には間違っているわけではありません。テストするのは難しいようです。もちろん、単体テストを行っておらず、擬似データストアを使う必要がない場合は、実際には関係ありません:)

私は通常MVC3をEntityFramework Code-Firstで使用してしまいます。あなたは実際のデータベースの代わりにList<T>でデータレイヤーのほとんどを模擬することができます。レコードをメモリー内のリストに「ロード」して「保存」し、実際のデータベースには絶対に触れることはできません。