我是第一次使用实体框架,我想知道我是否在最佳实践中使用.

我在我的业务逻辑中创建了一个单独的类,它将处理实体上下文.我的问题是,在我看过的所有视频中,他们通常将上下文包装在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语句执行业务逻辑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容器处理资源/对象的生命周期/处置.

如果你想知道更多的信息,请告诉我--因为有相当多的信息,甚至比这个令人惊讶的冗长的答案还要多.:)

Asp.net相关问答推荐

如何在 asp.net 服务器中使用字体

从组件属性调用异步方法的正确方法

.NET 框架 3.5 和 TLS 1.2

如何防止 IISExpress 和我的网站文件夹弄乱我的文档文件夹?

ASP .Net Web API 将图像下载为二进制

带有模型的 mvc 上传文件 - 第二个参数发布的文件为空

RestSharp 获取请求的完整 URL

跨子域共享 ASP.NET cookie

ASP.NET 在更新面板更新时显示正在加载...消息

将 ListItem 的 ASP.NET 列表数据绑定到 DropDownList 问题

如何在同一解决方案中从 MVC 项目调试 Web API 项目

如何在 IIS 7.5 上使用 ASP.NET 表单身份验证保护静态文件?

DropDownList AppendDataBoundItems(第一项为空白且无重复项)

这个rendersection的代码是什么意思?

在 ASP.NET 中使用 MasterPages 时使用 JQuery 的正确方法?

HtmlAgilityPack Select 的子 node 不符合预期

IISExpress 找不到使用 Visual Studio 2013 运行 localhost 的 ssl 页面

将 C# ASP.NET 数组传递给 Javascript 数组

LinkBut​​ton 向 OnClick 后面的代码发送值

Request.UserHostAddress 和 Request.ServerVariables["REMOTE_ADDR"].ToString() 有什么区别