如何处理不同的责任只使用一个DbContext实例 [英] How to handle different responsibilities while using only one instance of DbContext

查看:131
本文介绍了如何处理不同的责任只使用一个DbContext实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找我的问题的答案,但找不到一个答案,主要是因为我真的不知道如何说出来!



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



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



我已经看到,由于可能的内存泄漏,所有存储库都使用单个 DbContext 实例是不好的做法,所以我不能简单地调用 IDepartmentRepository 来获取新的部门,因为这将使用我的 DbContext 的单独实例。



对我来说,明显的解决方案是包括一些...

 部门GetDepartment(int id); 

IStaffRepository - 但这不会打破SRP?



我的控制器中的代码是...

 私有IStaffRepository存储库; 
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);

//由于不同的上下文导致错误
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;组; }
}

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>集合):this()
{
Collection = collection;
}
}

在数据库中有一个 int Department_ID 字段挂接到Department表。



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



  @ Html.DropDownListFor(m => m.SelectedDepartment,Model.DepartmentList, - 请选择 - )

对这个问题的长度表示歉意!

解决方案

如果所有的模型都是基于同一数据库中的实体,那么没有理由不使用单个上下文实例在同一个控制器中进行管理。我将使用简单的解决方案,并使用单个上下文实例。


I have been looking around for an answer to my question but couldn't find one, mostly because I don't really know how to phrase it!

I am playing around with EF code first and trying to implement some sort of repository pattern whilst using dependency injection (thanks to Unity). I am also trying to keep to SOLID (well, the SRP part at least) in that I have IStaffRepository and IDepartmentRepository interfaces which in turn implement IRepository<TEntity> which provides basic CRUD methods.

My question is, how can I keep to the SRP when I need to update a staff members' department?

I have read that it is bad practice to use a single DbContext instance for all repositories due to possible memory leaks and so I cannot simply call the IDepartmentRepository to get the new department as this would use a separate instance of my DbContext.

The obvious solution to me is to include something like...

Department GetDepartment(int id);

Within IStaffRepository - but would this not break the SRP?

The code I have in my Controller is...

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});
}

And the StaffMember model contains...

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

And the StaffViewModel looks like this...

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;
   }
}  

In the database there is a int Department_ID field which hooks up to the Department table.

I have a drop down in my view which looks like...

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

Apologies for the length of this question!

解决方案

If all of your models are based on entities in the same database, there is not reason not to use a single context instance to manage them within the same controller. I would go with the simple solution and use a single context instance.

这篇关于如何处理不同的责任只使用一个DbContext实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆