使用Entity Framework通过我的所有存储库共享数据上下文

时间:2011-11-27 09:54:26

标签: asp.net-mvc entity-framework

我有一个MVC3解决方案,我有2个存储库& 2个服务层。我也有单独的每一层:控制器< - >服务< - >存储库

以前,在我的每个存储库中,我都有一个单独的数据上下文。我是说我在每个存储库中创建了一个新的对象实例。我知道这不是好方法

所以我重构了我的解决方案,以便在我的存储库之间共享我的数据上下文。以下是我的解决方案的骨架。我想要你的意见。

public class EntityFrameworkDbContext: DbContext, IUnitOfWork
{
    public DbSet<Project>           Projects            { get; set; }
    public DbSet<Technology>        Technologies        { get; set; }

    public void Save()
    {
        SaveChanges();
    }
}

public interface IUnitOfWork
{
    void Save();
}

nInject绑定

ninjectKernel.Bind<IUnitOfWork>().To<EntityFrameworkDbContext>().InRequestScope();
ninjectKernel.Bind<IMainRepository>().To<MainRepository>();
ninjectKernel.Bind<IAdminRepository>().To<AdminRepository>();
ninjectKernel.Bind<IMainService>().To<MainService>();
ninjectKernel.Bind<IAdminService>().To<AdminService>();

控制器

public class AdminController : Controller
{
    private IMainService m_MainService;
    private IAdminService m_AdminService;

    public AdminController(IMainService mainService, IAdminService adminService)
    {
        m_MainService = mainService;
        m_AdminService = adminService;
    }
    ...
}

服务

public class MainService : IMainService
{
    private IMainRepository m_Repository;

    public MainService(IMainRepository repository)
    {
        m_Repository = repository;
    }
    ...
}

存储库

public class AdminRepository : IAdminRepository 
{
    private EntityFrameworkDbContext m_Context;

    public AdminRepository(IUnitOfWork unitOfWork)
    {
        if (unitOfWork == null)
            throw new ArgumentNullException("unitOfWork");

        m_Context = unitOfWork as EntityFrameworkDbContext;
    }
    ...
}

正如您所见,我实施了工作单元模式,但我不知道这是否是一种好方法。

感谢。

1 个答案:

答案 0 :(得分:1)

使用与MVC3和Linq2SQL类似的方法,所以我想这也适用于Entity Framework。只要确保向其他开发人员说明这一事实,默认情况下,如果没有另外说明,同一请求中的所有查询都使用相同的EF DbContext。

一句话:您实际上已将IUnitOfWork转换为存储库中的EntityFrameworkDbContext类型,我猜您不能将其替换为其他实现。发布给调用者是一个好主意,你期望IUnitOfWork(有1种方法),但是如果你传递EntityFrameworkDbContext,你的代码只会起作用吗?如果参数不是实际的EntityFrameworkDbContext

,我猜测代码会失败

如果您使用实际的EF datacontext,您可以使用Ninject将实际EntityFrameworkDbContext实例传递给所有呼叫者,如下所示:

//this makes sure all contexts use the same DbContext
ninjectKernel.Bind<EntityFrameworkDbContext>().To<EntityFrameworkDbContext>().InRequestScope();