这实际上取决于如何公开存储库/数据存储.
不确定你所说的"上下文将被关闭,因此我不能做业务逻辑"是什么意思.使用using语句执行业务逻辑inside.或者,如果您的业务逻辑在另一个类中,那么让我们继续.:)
有些人从他们的存储库返回具体的集合,在这种情况下,您可以将上下文包装在using语句中:
public class ArticleRepository
{
public List<Article> GetArticles()
{
List<Article> articles = null;
using (var db = new ArticleNetEntities())
{
articles = db.Articles.Where(something).Take(some).ToList();
}
}
}
这样做的好处是满足良好的连接实践——尽可能晚地打开,尽可能早地关闭.
您可以将所有业务逻辑封装在using语句中.
缺点-您的存储库会意识到业务逻辑,这是我个人不喜欢的,并且您最终会 for each 特定场景使用不同的方法.
second option-new将上下文作为存储库的一部分,并使其实现IDisposable.
public class ArticleRepository : IDisposable
{
ArticleNetEntities db;
public ArticleRepository()
{
db = new ArticleNetEntities();
}
public List<Article> GetArticles()
{
List<Article> articles = null;
db.Articles.Where(something).Take(some).ToList();
}
public void Dispose()
{
db.Dispose();
}
}
然后:
using (var repository = new ArticleRepository())
{
var articles = repository.GetArticles();
}
或者third-option(我最喜欢的),用dependency injection.将所有上下文工作与您的存储库分离,并让DI容器处理资源的处置:
public class ArticleRepository
{
private IObjectContext _ctx;
public ArticleRepository(IObjectContext ctx)
{
_ctx = ctx;
}
public IQueryable<Article> Find()
{
return _ctx.Articles;
}
}
您 Select 的DI容器将向存储库的实例化中注入具体的ObjectContext,并配置一个生命周期(Singleton、HttpContext、ThreadLocal等),然后根据该配置对其进行处理.
我对它进行了设置,这样每个HTTP请求都会得到一个新的上下文.当请求完成时,我的DI容器将自动处理上下文.
我还在这里使用工作单元模式,允许多个存储库使用一个对象上下文.
您可能还注意到,我更喜欢从我的存储库返回IQueryable(而不是具体的列表).要强大得多(但如果你不理解其中的含义,那就有风险).我的服务层在IQueryable上执行业务逻辑,然后将具体集合返回给UI.
这是我迄今为止最强大的选项,因为它允许一个简单的存储库,工作单元管理上下文,服务层管理业务逻辑,DI容器处理资源/对象的生命周期/处置.
如果你想知道更多的信息,请告诉我--因为有相当多的信息,甚至比这个令人惊讶的冗长的答案还要多.:)