1

我一直在寻找我的问题的答案,但找不到答案,主要是因为我真的不知道如何表达它!

我首先在玩 EF 代码,并尝试在使用依赖注入的同时实现某种存储库模式(感谢 Unity)。我还试图保持 SOLID(至少是 SRP 部分),因为我拥有IStaffRepositoryIDepartmentRepository接口,这些接口又实现IRepository<TEntity>了提供基本CRUD方法的接口。

我的问题是,当我需要更新员工的部门时,如何保持 SRP?

我已经读过,由于可能的内存泄漏,对所有存储库使用单个DbContext实例是不好的做法,所以我不能简单地调用IDepartmentRepository来获取新部门,因为这将使用 my 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与部门表挂钩的字段。

我的视图中有一个下拉菜单,看起来像...

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

为这个问题的长度道歉!

4

3 回答 3

1

如果您的所有模型都基于同一数据库中的实体,则没有理由不在同一控制器中使用单个上下文实例来管理它们。我会采用简单的解决方案并使用单个上下文实例。

于 2011-11-04T14:28:27.177 回答
0

单个实例的潜在问题是完成后没有释放上下文。如果您使用依赖注入,这将在完成后处理此对象的处置。我也不推荐你上面的设计——你给你的 ViewModel 数据访问行为,通常它们不是目的。ViewModel 具有模型的属性,并且可能具有一些特定于准备该数据的功能。将服务层注入您的控制器,其职责是填充该视图模型或返回模型。然后,您可以使用 automapper 将该模型映射到您的 ViewModel。还有一个简洁的属性可以用来做这个映射。

查看: http: //lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/

于 2011-11-04T16:18:29.247 回答
0

如果您使用的是存储库模式,那么您至少有一个实现多个存储库接口之一的类。由于您的代码与接口而不是与实现耦合,因此您不必担心。但是,您应该将存储库实现视为单例,即每个方法都应该是独立的,并且类不应存储状态(您可以存储连接字符串,因为它基本上是一个常量)。所以一个方法看起来像这样

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

这样你总是在处理数据上下文,因此不应该有内存泄漏 至于 SRP,存储库的作用是获取/保存对象。如果是这样,那很好。

于 2011-11-04T14:39:38.777 回答