2011-04-20 29 views
0

基本上我有一个存储库,可以控制对我EF模型的访问。它创建引用,然后根据正在访问的Repository,返回请求的实体。现在我正在公开一个IQueryable Get方法,该方法将直接从实例ObjectContext中返回实体。好的做法告诉我,我应该在using语句中包装任何ObjectContext,以确保它正确地处理,但是当我从存储库执行此操作时,出现ObjectContext在控制器加载时已经处理的错误。我已经删除了使用,然后它工作得很好,但我想知道如何通常应该这样做。我想维护一个IQueryable返回,因为我可能需要在其上执行各种命令。有什么建议么?如果多个HTTP请求开始进入,EF是否帮助保护我免于打开连接?实体框架和存储库,将开放的上下文传递给控制器​​是否安全?

错误了:

public IQueryable<IUser> Get 
    { 
     get 
     { 
      using (var context = new DrinkersPassportEntities(_connString)) 
      { 
       return context.Users.AsQueryable(); 
      } 
     } 
    } 

工作,但是没有帮我彻夜难眠:

public IQueryable<IUser> Get 
    { 
     get 
     { 
      var context = new DrinkersPassportEntities(_connString); 
      return context.Users.AsQueryable(); 
     } 
    } 

我所有的控制器目前正在做的是:

public ViewResult Index() 
    { 

     return View(userRepo.Get); 
    } 

回答

1

有些人会我告诉你你的存储库不应该返回Queryables ....但我不买这个。

确实要确保处置ObjectContext,否则最终会发生内存泄漏(特别是因为它可以保留所有物化实体)。

一个常见的解决方案是使用每个请求的ObjectContext生存期。也就是说,将ObjectContext存储在ASP .NET的Request对象中,并处理HttpApplication.EndRequest事件,此时您将处理ObjectContext。

+0

我会研究有关从存储库返回的IQueryable的第一行,因为我不知道这一点。 (这是我第一次执行所有正在实现的内容,即mvc,ef 4,Repository模式和依赖注入) 至于每个请求的ObjectContext,如果上下文要么在Web应用程序中而不是在我的存储库中被终止和/或生成? – SenseiHitokiri 2011-04-21 00:17:37

+0

根据您对每个请求ObjectContext的建议进行了大量的阅读后,我发现了一条很好的路径。尽管乍得的评论在技术上也是正确的,但网络仍然有着避免IQueryable的理由。 建议在线说我应该抽象HttpContext创建一个延迟加载currentContext,然后注入它。看起来这就是明天我会花钱的地方。还没有弄清楚在哪里处理我的ObjectContext,但至少它可以从HttpContext中获得。我的猜测是我可以在某处实现IDisposable。谢谢! – SenseiHitokiri 2011-04-21 06:16:13

+0

这是燃烧的理由,以避免IQueryables,我尊重他们中的一些,但它是不可维护的恕我直言,必须编写500库方法,如GetCustomerById,GetCustomerByFirstName,GetCustomerByFirstNameAndLastName,GetCustomerByFirstNameLastNameAndMiddleName。你最终会遇到一个充斥着重复和滥用功能的仓库。我宁愿公开一个IQueryable。 – Jeff 2011-04-21 14:20:34

0

确定它是安全的。很多人将数据存取出来并最终有2-3层用于数据访问,只要确保代码清洁即可。你如何得到你的物品取决于你,我认为务实的是下注的方式。我认为给定类型有一个单独的Repository/Service类来帮助抽象出重用的特定查询是很好的,但是在控制器中直接公开上下文没什么意义。