我先用ASP.NET MVC和实体框架代码创建一个应用程序。我正在使用存储库和工作模式的单元,影响来自以下链接。
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
这里我对工作单元的实现有疑问,链接工作单元是通过直接在类本身中编写实体来实现的,比如。
public class UnitOfWork : IDisposable
{
private SchoolContext context = new SchoolContext();
private GenericRepository<Department> departmentRepository;
public GenericRepository<Department> DepartmentRepository
{
get
{
if (this.departmentRepository == null)
{
this.departmentRepository = new GenericRepository<Department>(context);
}
return departmentRepository;
}
}
}你认为这个实现足够好吗,因为每次我添加/删除实体时,我都需要改变我的工作单元类。我认为工作单元不应该依赖于实体。因为在我的应用程序中,根据客户的反馈,我们将频繁地添加/删除实体。
我可能听起来很愚蠢,但请让我知道你对此的看法。
发布于 2014-04-17 02:18:29
实体框架中已经实现了Unit of Work模式。
DbContext是您的工作单元。每个IDbSet都是一个存储库。
using (var context = new SchoolContext()) // instantiate our Unit of Work
{
var department = context.Departments.Find(id);
}发布于 2014-04-17 22:18:46
UnitOfWorkPattern有几种风格。您描述的是一个显示所有内容的方法,还有一种隐藏所有内容的方法。
public YourContext : DbContext, IContext{}
public interface IUnitOfWork{
void Commit();
}
public UnitOfWork : IUnitOfWork{
private readonly IContext _context;
//IOC should always inject the same instance of this, register it accordingly
public UnitOfWork(IContext context){
_context = context;
}
void Commit(){
// try catch the validation exception if you want to return the validations this
// way if your confident you've already validated you can put a void here or
// return the intfrom save changes make sure you handle the disposing properly,
// not going into that here you also may be doing other stuff here, have multiple
// "contexts" to save in a single transaction or we have contextProcessors that
// do stuff based on items in the context
_context.SaveChanges();
}
}这就留下了一个问题,如果您不从UnitOfWork获取存储库,那么如何将它们放入需要它们的类中。这最好由IOC框架来处理。同样,这里有几个选项。一次是将UnitOfWork注册为每个请求的单个实例,并将其注入到自定义Repository类中。
public interface IRepository<T>
{
IQueryable<T> Records();
//other methods go here
}
public Repository : IRepository<T>
{
private IContext _context;
// same instance of context injected into the unit of work, this why when you Commit
// everything will save, this can get tricky if you start adding Add, Update and stuff
// but EF does have the support needed.
public Repository(IContext context)
{
_context = context;
}
public Records()
{
return _context.Set<T>();
}
}
public class SomeService : ISomeService{
private readonly _myObjectRepository;
public SomeService(IRepository<MyObject> myObjectRepository){
_myObjectRepository = myObjectRepository;
}
}就我个人而言,我认为IDbSet是一个足够的抽象,所以我不再创建存储库。但是,为了从上下文注入IDbSets,您需要将它们注册为您在IOC设置中从上下文提取的实例。这可能很复杂,根据您的技能,您可能会发现自己处于必须注册每个IDbSet的情况下,而我知道您正在努力避免。
使用IDbSet的好处是您可以访问像Add这样的简单方法,并且可以在一般意义上避免使用Entity和DbEntity的一些更复杂的部分。
public class SomeService : ISomeService {
private readonly _myObjectSet;
// requires specialized IOC configurations because you have to pull this instance from
// the instance of the context, personally don't know how to do this with a single
// registration so this has the same problem as having to add each new repository to the
// unit of work. In this case each new Entity I add to the context requires I add an IOC
// registration for the type.
public SomeService(IDbSet<MyObject> myObjectSet){
_myObjectSet= myObjectSet;
}
}发布于 2014-04-16 23:11:46
尝试将SchoolContext传递给GenericRepository:
public GenericRepository<T>
{
private SchoolContext _context;
public GenericRepository(SchoolContext context)
{
_context = context;
}
public Get(int id)
{
return _context.Set<T>().Find(id);
}
}并使用:
using(var context = new SchoolContext())
{
var departmentRepository = new GenericRepository<Department>(context);
var department = departmentRepository.Get(1);
}https://stackoverflow.com/questions/23111868
复制相似问题