1

私は自分の質問に対する答えを探していましたが、それを見つけることができませんでした。主な理由は、それを表現する方法が本当にわからないためです。

私は最初にEFコードで遊んでいて、依存性注入を使用しながら、ある種のリポジトリパターンを実装しようとしています(Unityのおかげで)。私はまた、基本的なメソッドを提供するインターフェースを持っIStaffRepositoryているという点で、SOLID(少なくともSRPの部分)を維持しようとしています。IDepartmentRepositoryIRepository<TEntity>CRUD

私の質問は、スタッフの部門を更新する必要がある場合、どうすればSRPを維持できますか?

DbContextメモリリークの可能性があるため、すべてのリポジトリに単一のインスタンスを使用することは悪い習慣であると読みました。そのため、を呼び出しIDepartmentRepositoryて新しい部門を取得することはできません。これは、の別のインスタンスを使用するためDbContextです。

私にとって明らかな解決策は、次のようなものを含めることです...

Department GetDepartment(int id);

IStaffRepository-しかし、これはSRPを壊しませんか?

私のコントローラーにあるコードは...

private IStaffRepository repository;
private IDepartmentRepository departmentRepository;

public StaffController(IStaffRepository repository, IDepartmentRepository departmentRepository)
{
   this.repository = repository;
   this.departmentRepository = departmentRepository;
}

public ActionResult Edit(int id)
{
   return View(new StaffViewModel(repository.GetItem(id)));
}

[HttpPost]
public ActionResult Edit(int id, StaffViewModel model)
{
   if (!ModelState.IsValid)
      return View(model);

   var item = repository.GetItem(id);

   // throws error due to different context
   item.Department = departmentRepository.GetItem(int.Parse(model.SelectedDepartment));

   UpdateModel(item, "Item");

   repository.Save();

   return RedirectToAction("Member", new {id});
}

そしてStaffMemberモデルには...

public class StaffMember
{
   public virtual Department Department { get; set; }
}

そして、StaffViewModelこのように見えます...

public class StaffViewModel : ViewModelBase<StaffMember>
{
   public SelectList DepartmentList {get;set;}
   public string SelectedDepartment {get;set;}

   public StaffViewModel()
   {
      var departmentRepository = new DepartmentRepository();
      DepartmentList = new SelectList(departmentRepository.GetCollection(), "ID", "Title", SelectedDepartment);   
   }

   public StaffViewModel(StaffMember item) : this()
   {
      Item = item;
      SelectedDepartment = Item.Department.ID.ToString();
   }

   public StaffViewModel(List<StaffMember> collection) : this()
   {
      Collection = collection;
   }
}  

データベースにはint Department_ID、Departmentテーブルに接続するフィールドがあります。

ビューにドロップダウンがあります...

@Html.DropDownListFor(m => m.SelectedDepartment, Model.DepartmentList, "--Please Select--")

この質問の長さについてお詫びします!

4

3 に答える 3

1

すべてのモデルが同じデータベース内のエンティティに基づいている場合、同じコントローラー内でそれらを管理するために単一のコンテキストインスタンスを使用しない理由はありません。単純なソリューションを使用して、単一のコンテキストインスタンスを使用します。

于 2011-11-04T14:28:27.177 に答える
0

リポジトリパターンを使用している場合は、少なくとも1つ以上のリポジトリインターフェイスを実装するクラスがあります。コードは実装ではなくインターフェースに結合されているため、心配する必要はありません。ただし、リポジトリの実装をシングルトンとして扱う必要があります。つまり、すべてのメソッドが独立していて、クラスが状態を格納しないようにする必要があります(基本的に定数であるため、接続文字列を格納できます)。したがって、メソッドは次のようになります

public void Save(Entity entity)
{
   using(var db=new MyDbContext())
   {
      //do stuff
   }
}

このようにすると、常にデータコンテキストを破棄するため、メモリリークが発生しないはずです。SRPの場合、リポジトリの役割はオブジェクトを取得/保存することです。そうすればそれは良いことです。

于 2011-11-04T14:39:38.777 に答える
0

単一のインスタンスで発生する可能性のある問題は、実行時にコンテキストを解放しないことです。依存性注入を使用する場合、これは、実行時にこのオブジェクトの破棄を処理します。上記のデザインもお勧めしません。ViewModelデータアクセス動作を提供しているのですが、これは一般的には意図されていません。ViewModelにはモデルのプロパティがあり、そのデータを準備するために固有の機能がある場合があります。そのビューモデルにデータを入力するか、モデルを返す責任があるコントローラーにサービスレイヤーを挿入します。次に、オートマッパーを使用して、そのモデルをViewModelにマップできます。このマッピングを行うために利用できるきちんとした属性もあります。

チェックアウト: http: //lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/

于 2011-11-04T16:18:29.247 に答える