我是第一次使用Entity框架,并且想知道我是否在最佳实践中使用它。

我在业务逻辑中创建了一个单独的类,该类将处理实体上下文。我遇到的问题是,在我看到的所有视频中,它们通常将上下文包装在using语句中以确保其闭合,但是显然我无法在我的业务逻辑中做到这一点,因为在我可以实际关闭上下文之前用它?

那我在做什么吗?几个例子:

    public IEnumerable<Article> GetLatestArticles(bool Authorised)
    {
        var ctx = new ArticleNetEntities();
        return ctx.Articles.Where(x => x.IsApproved == Authorised).OrderBy(x => x.ArticleDate);
    }

    public IEnumerable<Article> GetArticlesByMember(int MemberId, bool Authorised)
    {
        var ctx = new ArticleNetEntities();
        return ctx.Articles.Where(x => x.MemberID == MemberId && x.IsApproved == Authorised).OrderBy(x => x.ArticleDate);
    }

我只想确保我不会构建很多人都会用到的东西?

最佳答案

这实际上取决于如何公开您的存储库/数据存储。

不知道您的意思是“上下文将被关闭,因此我无法进行业务逻辑”。在using语句中进行业务逻辑处理。或者,如果您的业务逻辑位于不同的类中,那么让我们继续。 :)

某些人从其存储库返回具体的集合,在这种情况下,您可以将上下文包装在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语句内。

缺点-您的存储库意识到我个人不喜欢的业务逻辑,并且最终针对每种特定方案使用了不同的方法。

第二个选项-将上下文作为存储库的一部分,并使其实现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();
}

第三选项(我的最爱),请使用依赖项注入(inject)。将所有上下文工作与存储库解耦,并让DI容器处理资源的处置:
public class ArticleRepository
{
   private IObjectContext _ctx;

   public ArticleRepository(IObjectContext ctx)
   {
      _ctx = ctx;
   }

   public IQueryable<Article> Find()
   {
      return _ctx.Articles;
   }
}

您选择的DI容器将使用配置的生存期(Singleton,HttpContext,ThreadLocal等)将具体的ObjectContext注入(inject)到存储库的实例中,然后根据该配置进行处理。

我进行了设置,因此每个HTTP请求都获得了一个新的上下文。请求完成后,我的DI容器将自动处理上下文。

我还在这里使用工作单位模式来允许多个存储库与一个对象上下文一起工作。

您可能还注意到,我更喜欢从存储库中返回IQueryable(而不是具体的List)。功能强大得多(但如果您不了解其中的含义,那就有风险了)。我的服务层在IQueryable上执行业务逻辑,然后将具体集合返回到UI。

这是我迄今为止最强大的选择,因为它允许使用简单的仓库,工作单元管理上下文,服务层管理业务逻辑,DI容器处理资源/对象的生命周期/处置。

让我知道您是否需要更多信息-因为有很多信息,甚至比这个令人惊讶的冗长答案还要多。 :)

09-28 05:59