Asp.net mvc 使用实体框架共享所有存储库的数据上下文
我有一个MVC3解决方案,其中我有两个存储库和两个服务层。我还有单独的每一层:控制器服务存储库 以前,在我的每个存储库中,我都有一个单独的数据上下文。我的意思是,我在每个存储库中创建了一个新的对象实例。我知道这不是好办法 所以我重构了我的解决方案,以便在我的存储库之间共享我的数据上下文。下面是我的解决方案的框架。我想听听你的意见Asp.net mvc 使用实体框架共享所有存储库的数据上下文,asp.net-mvc,entity-framework,Asp.net Mvc,Entity Framework,我有一个MVC3解决方案,其中我有两个存储库和两个服务层。我还有单独的每一层:控制器服务存储库 以前,在我的每个存储库中,我都有一个单独的数据上下文。我的意思是,我在每个存储库中创建了一个新的对象实例。我知道这不是好办法 所以我重构了我的解决方案,以便在我的存储库之间共享我的数据上下文。下面是我的解决方案的框架。我想听听你的意见 public class EntityFrameworkDbContext: DbContext, IUnitOfWork { public DbSet<
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();
}
服务
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;
}
...
}
正如您所看到的,我实现了工作单元模式,但我不知道这是否是一个好方法
谢谢。对MVC3和Linq2SQL使用了类似的方法,所以我想这也适用于实体框架。只需确保告诉其他开发人员一个事实,即默认情况下,同一请求中的所有查询都使用相同的EF DbContext(如果没有告诉其他人) 一句话:您正在有效地将您的
IUnitOfWork
强制转换为存储库中的EntityFrameworkBContext
类型,我想您不能用另一个实现来替换它。如果您希望IUnitOfWork
(有1个方法),但在后台,您的代码仅在传递entityframeworkbcontext
时才起作用,那么向调用者发布是一个好主意吗?如果参数不是实际的EntityFrameworkBContext
,我猜代码会失败
如果使用该实际EF datacontext,则可以使用Ninject将实际的EntityFrameworkBContext
实例传递给所有调用方,如下所示:
//this makes sure all contexts use the same DbContext
ninjectKernel.Bind<EntityFrameworkDbContext>().To<EntityFrameworkDbContext>().InRequestScope();
//这确保所有上下文使用相同的DbContext
ninjectKernel.Bind().To().InRequestScope();
谢谢您的建议。我不太理解您的代码ninjectKernel.Bind().To().InRequestScope();您的意思是,通过这个简单的绑定,数据上下文将被共享吗?我已经在这方面实施了工作单元……是的,它的意思就是这样。您的代码请求EntityFrameworkBContext类型,它将获得EntityFrameworkBContext的实例。RequestScope确保它在任何给定Http请求中都是相同的实例。如果你只是为了这个目的而使用UnitOfWork,那么它就有点多余了……而且,看到同一代码中的IUnitOfWork和Repository,我会想到这一点。建议你阅读它,并决定它是否适用于你目前的情况。非常有趣的文章。我删除了解决方案中的所有UnitOfWork,并对其进行了测试。你是对的,在我的解决方案中,我现在不需要它。你的解决方案很有效。不管怎样,谢谢你。用这个来处理EF启动两个不同的上下文来拉两个不同的实体(以及由此产生的问题)会有什么不利之处
public class AdminRepository : IAdminRepository
{
private EntityFrameworkDbContext m_Context;
public AdminRepository(IUnitOfWork unitOfWork)
{
if (unitOfWork == null)
throw new ArgumentNullException("unitOfWork");
m_Context = unitOfWork as EntityFrameworkDbContext;
}
...
}
//this makes sure all contexts use the same DbContext
ninjectKernel.Bind<EntityFrameworkDbContext>().To<EntityFrameworkDbContext>().InRequestScope();