首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >工作模式实现单元

工作模式实现单元
EN

Stack Overflow用户
提问于 2014-04-16 22:08:02
回答 3查看 14.5K关注 0票数 12

我先用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

这里我对工作单元的实现有疑问,链接工作单元是通过直接在类本身中编写实体来实现的,比如。

代码语言:javascript
复制
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;
        }
    }

}

你认为这个实现足够好吗,因为每次我添加/删除实体时,我都需要改变我的工作单元类。我认为工作单元不应该依赖于实体。因为在我的应用程序中,根据客户的反馈,我们将频繁地添加/删除实体。

我可能听起来很愚蠢,但请让我知道你对此的看法。

EN

回答 3

Stack Overflow用户

发布于 2014-04-17 02:18:29

实体框架中已经实现了Unit of Work模式。

DbContext是您的工作单元。每个IDbSet都是一个存储库。

代码语言:javascript
复制
using (var context = new SchoolContext())   // instantiate our Unit of Work
{
    var department = context.Departments.Find(id);
}
票数 22
EN

Stack Overflow用户

发布于 2014-04-17 22:18:46

UnitOfWorkPattern有几种风格。您描述的是一个显示所有内容的方法,还有一种隐藏所有内容的方法。

代码语言:javascript
复制
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类中。

代码语言:javascript
复制
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的一些更复杂的部分。

代码语言:javascript
复制
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;
    }
}
票数 8
EN

Stack Overflow用户

发布于 2014-04-16 23:11:46

尝试将SchoolContext传递给GenericRepository:

代码语言:javascript
复制
public GenericRepository<T>
{
    private SchoolContext _context;

    public GenericRepository(SchoolContext context)
    {
       _context = context;
    }

    public Get(int id)
    {
        return _context.Set<T>().Find(id);
    }
}

并使用:

代码语言:javascript
复制
using(var context = new SchoolContext())
{
    var departmentRepository = new GenericRepository<Department>(context);
    var department = departmentRepository.Get(1);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23111868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档