【问题标题】:Entity Framework and ObjectContext n-tier architecture实体框架和 ObjectContext n 层架构
【发布时间】:2012-03-04 22:37:44
【问题描述】:

我有一个基于非常经典的不同层的 n 层应用程序:用户界面、服务 (WCF)、业务逻辑和数据访问。

数据库(Sql Server)显然是通过实体框架查询的,问题基本上是每个调用都从用户界面开始并经过所有层,但是这样做我需要每次为每个操作创建一个新的 ObjectContext 并且使性能非常糟糕,因为每次我需要重新加载元数据并重新编译查询。

最推荐的模式是下面的模式,这也是我实际在做的:每次服务接收到调用时,通过业务层方法创建和传递新上下文

 public BusinessObject GetQuery(){     
   using (MyObjectContext context = new MyObjectContext()){ 
      //..do something  }    }

对于简单的查询,我没有看到任何特定的交易,它工作正常,但对于复杂和繁重的查询,它会进行 2 秒的查询,每次调用会持续大约 15 秒。

我可以将 ObjectContext 设置为静态,它可以解决性能问题,但似乎没有人建议,还因为我无法从不同的线程同时访问上下文,并且多个调用会引发例外。我可以让它成为线程安全的,但长时间保持相同的 ObjectContext 使它变得越来越大(而且速度越来越慢),因为它导入每个查询的引用它执行一个查询。

我认为它是最常见的架构,那么实现和使用 ObjectContext 的最佳和已知方式是什么?

谢谢, 马可

【问题讨论】:

    标签: performance linq entity-framework entity-framework-4 linq-to-entities


    【解决方案1】:

    使用静态对象上下文不是一个好主意。静态上下文将由 Web 应用程序的所有用户共享,这意味着当一个用户对上下文进行修改(例如调用 saveChanges)时,所有其他使用该上下文的用户都会受到影响(假设他们已经添加或更新了这将是一个问题数据到上下文但没有调用保存更改)。使用对象上下文的最佳实践是在请求期间保持其活动状态,并使用 if 来执行任何原子业务操作。您可能想查看 UnitOfWork 模式和存储库模式

    uow

    uow and repository in EF

    如果您觉得您的查询存在性能问题,并且您可能会重复使用您的查询,我建议您使用预编译的 linq 查询。您可以查看下面的链接以获取更多信息

    precompiled linq julie lermann

    precompiled linq

    【讨论】:

      【解决方案2】:

      您展示的是使用上下文的典型模式 - 按请求,类似于使用数据库连接。

      是什么让您认为糟糕的表现与重新创建上下文有关?这很可能不是这种情况。您如何衡量这种影响?

      如果你有这样的性能关键代码,这种开销真的很重要,你不应该使用实体框架,因为总会有一些开销,即使在一般情况下开销应该很小。不过,我将开始关注您的数据模型和基础数据存储,这将对您的查询性能产生更大的影响。您是否优化了查询?你把索引放在你需要的地方了吗?您可以对数据进行反规范化以删除连接吗?

      【讨论】:

      • 我曾尝试在同一个调用中多次执行同一个查询,只有第一次需要很长时间,其他的几乎与 SQL Management Studio 相同的时间!当我使用单例模式并将 ObjectContext 设置为静态时,它的行为也是一样的。所以我认为问题出在我声明一个新的 ObjectContext 时,不是吗?
      • 第一次初始化 ObjectContext 和 MetaData。这就是为什么它第一次很慢。您的元数据为每个 AppDomain 缓存一次。
      • 对不起,我不明白我做错了什么,每次调用 werbservice 并创建一个新的 ObjectContext 时都很慢
      【解决方案3】:

      在 Web 上下文中,最好使用无状态方法并为每个请求创建一个 ObjectContext

      ObjectContext 的构建成本极低。元数据是从全局缓存中加载的,因此只有第一次调用才需要加载它。

      静态绝对不是一个好主意。 ObjectContext 不是线程保存的,当在具有多个调用的 WCF 服务中使用它时会导致问题。使其线程保存会导致性能下降,并且在多个请求中重用它时可能会导致细微的错误。

      查看此信息:How to decide on a lifetime for your ObjectContext

      【讨论】:

      • 是的,我已经阅读了那篇文章,这就是为什么我不使用单例模式的原因,我不明白为什么每次创建新的复杂查询时性能如此糟糕对象上下文
      • “每次”是什么意思?是在重新编译您的代码并启动您的应用程序时吗?还是在多次执行一个函数的时候?
      • 我的意思是每次用户界面调用服务它都会创建一个新的ObjectContext,执行一个查询并返回一些结果,每次我做这个操作都很慢,如果我在同样的调用它只是第一次很慢
      • 很遗憾没有,因为代码是受保护的,我不能把它带到这里
      • 你能在一个简单的控制台应用程序中重现你的问题吗?在没有任何额外内容的情况下重新创建您的问题是解决问题的第一步:)
      猜你喜欢
      • 2012-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 2015-06-30
      • 1970-01-01
      • 2013-10-12
      • 1970-01-01
      相关资源
      最近更新 更多