2013-04-22 49 views
1

我在我的项目上建立了DI注入,注入IUnitOfWork的实现,该实现有我的存储库和Commit()方法。我把这个注入到我的业务层中,一切都很好。DI,实体框架和延期执行

public Business(IUnitOfWork context) { 
    this.Context = context; 
} 

public IEnumerable<User> ExpiredUsers() { 
    return this.Context.Users.Query().Where(u => u.Expired == true); 
} 

这商务舱注入到我的控制器

public class UsersController : Controller { 
    public UsersController(Business business) { 
     this.Business = business; 
    } 

    public ActionResult Home() { 
     return View(new HomeViewModel(business.ExpiredUsers()); 
    } 
} 

用户是一个IQueryable,和我的商业方法使用实体框架很好地转化为SQL。我的问题是,在执行此方法后,查询用户对象上的属性,从而导致延迟执行。在我的情况下,说视图中的东西进入每个用户的地址.State.Cities,或其他一些导致推迟执行和查询数据库的属性n次。

我已经设置DI,使用Ninject为每个请求创建数据库上下文(IUnitOfWork)。由于数据库上下文仍处于打开状态,因此我不知道如何防止发生这种情况。我宁愿视图抛出异常;以便我可以尽早地发现这些问题。为了完整起见,这里是我的模块。

public class Module : NinjectModule 
{ 
    public override void Load() 
    { 
     this.Bind<IUnitOfWork>().To<SqlUnitOfWork>().InRequestScope(); 
    } 
} 
+0

是在address.State.Cities查看内部或视图模型里面发生了什么?如果它位于视图内部,那么视图未编译的事实将迫使你的上下文发出额外的查询。 – andresuribe 2013-04-22 03:59:50

回答

-1

强制ExpiredUsers通过调用ToList()来枚举列表:

return this.Context.Users.Query().Where(u => u.Expired == true).ToList(); 
+0

会很有趣,看到downvote的原因 - 不知道还有多少人可以防止多次枚举'ExpiredUsers'结果的代码不会导致多个查询执行... – 2013-04-22 04:08:05

+0

这会将数据带入调用ToList()的内存,但它并不妨碍该观点导致推迟执行,至少在我的情况下。我想知道InRequestScope是否太大,如果我可以限制它到商务类。 – Michael 2013-04-22 04:08:07

+0

我又看了一遍 - 看起来你正在收集一系列查询,这就是为什么每次更新时都要执行的原因。尝试更改函数以实际执行查询而不是返回查询。 – Gjeltema 2013-04-22 04:32:18