2012-03-19 66 views
0

为了支持EF中的延迟加载功能,实例化DbContext的最佳方法是什么?什么是为ASP.NET MVC创建EF DbContext实例的最佳方法

我知道HttpContext目前的产品通过Application_BeginRequest方法和Application_EndRequest方法来创建DbContext好地方,但在MSDN和官方asp.net的MVC网站的一些示例代码,他们只是在控制器的构造函数创建DbContext和处置它控制器的Dispose()方法。

我认为这两种方式都不是太不同,因为所有这些都实现会话每请求模式。

我只是想确保我的理解是否正确。

回答

1

控制器中的Dispose()方法并不总是可靠的。同样,Session也可能不是一个好主意。 “最佳”可能是主观的,但通过使用依赖注入(Castle Windsor)和遵循工作单元库模式,我们取得了最好的成功。

安装工作的单位大致如下:

public class UnitOfWork : IUnitOfWork 
{ 
    public UnitOfWork() 
    { 
     this.Context = new MyEFEntities(); 
     this.Context.ContextOptions.LazyLoadingEnabled = true; 
    } 

    public void Dispose() 
    { 
     this.Context.Dispose(); 
    } 

    public ObjectContext Context { get; internal set; } 
} 

设置你的资料库:在Global.asax中与城堡

public class Repository<TEntity> : IRepository<TEntity> 
    where TEntity : class 
{ 
    public Repository(IUnitOfWork unitOfWork) 
    { 
     Context = unitOfWork.Context; 
     ObjectSet = Context.CreateObjectSet<TEntity>(); 
    } 
    public ObjectContext Context { get; set; } 
    public IObjectSet<TEntity> ObjectSet { get; set; } 
} 

注册:

void Application_Start() 
{ 
    this.Container.Register(
     Component.For<IUnitOfWork>() 
      .UsingFactoryMethod(() => new UnitOfWork()) 
      .LifeStyle 
      .Is(LifestyleType.PerWebRequest) 
     ); 

    ControllerBuilder.Current.SetControllerFactory(
     new WindsorControllerFactory(this.Container)); 
} 

和使用您的控制器(或您使用它的任何地方,只要它是可注射的):

public class SomeController 
{ 
    public SomeController(IRepository<MyEntity> repository) 
    { 
     this.Repository = repository; 
    } 

    public IRepository<MyEntity> Repository { get; set; } 

    public ActionResult MyAction() 
    { 
     ViewData.Model = this.Repository.ObjectSet.Single(x => x.Condition); //or something... 
    } 
} 
+0

感谢您的回复lukiffer,但我的问题集中在更基础的东西不存储库,而不是DI的东西。我只是想知道什么方法在begin/endrequest事件或控制器类中最好,而不使用存储库和DI容器。 – Ray 2012-03-19 05:40:07

+0

通过附加到开始/结束请求事件,您可以在请求的整个生命周期中访问相同的datacontext实例,而不仅仅是在控制器中(例如过滤器等),但最终它们是相同的。我提出长篇解释的唯一原因是因为我在网上农场/网络花园的请求上下文中遇到了问题,最终这是唯一有效的工作。 – lukiffer 2012-03-19 05:46:07

+0

你的意思是这两种方式都可以支持延迟加载,对吧? – Ray 2012-03-19 15:13:01

1

这里的任何延迟加载都有可能成为未来问题的陷阱。没有DI,没有存储库 - 很难看到任何工作,没有对延迟加载的破解。你也打算将你的实体传递给你的观点。如果是这样,这将造成重叠不良。控制器应为您的视图打包数据,而不是在您的视图中稍后评估。

对于MVC最佳实践,您应尽可能将视域模型平铺到视图模型中(如果拼合有意义)并使用视图模型。既然你理想的情况下知道什么会被延迟加载,那么将前面的命中并在查询中使用.Include()来加载负载可能更有意义,否则可以向数据库发出很多查询。

0

我已经使用会话工厂模式并将DBContext保存在会话对象中。它将保持每个会话的开放。到目前为止,我没有遇到任何问题。

相关问题