0

我有一个基于经典不同层次的n层应用程序:用户界面,服务(WCF),业务逻辑和数据访问。数据库(Sql Server)显然是通过实体框架被打破的,问题基本上是每个调用都从用户界面开始并贯穿所有层,但这样做需要每次为每个操作创建一个新的ObjectContext,这使得性能非常糟糕,因为每次我需要重新加载元数据并重新编译查询。实体框架和ObjectContext n层体系结构

最建议图案这将是下面的一个,它是什么,我实际上做:创造和传递新的上下文throught每个服务接收到呼叫

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

为了便于实时业务层的方法查询我没有看到任何特定的dealy,它工作正常,但对于复杂和沉重的查询,它使2秒钟的查询继续每次调用15秒。

我可以设置ObjectContext静态,它可以解决性能问题,但它似乎不被任何人建议,也因为我不能同时从不同的线程和多个调用同时访问上下文一个例外。我可以让它成为线程安全的,但长时间维持相同的ObjectContext会使它变得越来越大(并且越来越慢),因为它导入的引用每个查询都会执行查询。

我拥有的体系结构我认为这是最常见的,那么实现和使用ObjectContext的最佳方法是什么?

谢谢 马尔科

回答

2

在Web方面,最好使用无状态的方式,并为每个请求创建一个ObjectContext

ObjectContext建设的成本是最小的。元数据从全局缓存中加载,因此只有第一次调用才会加载它。

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

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

+0

是的,我已经读了文章,这就是为什么我不使用Singleton模式,我不明白为什么当我每次创建一个新的objectcontext时,对于复杂查询来说性能很糟糕 – MaRuf 2012-02-13 14:29:52

+0

'每次'都是什么意思?那是在重新编译你的代码并启动你的应用程序?还是多次执行一个函数? – 2012-02-13 14:33:22

+0

我的意思是每次用户界面调用服务时,它会创建一个新的ObjectContext,执行一个查询并返回一些结果,每次我执行此操作时它都很慢,如果我在同一个调用中执行此操作多次,第一次 – MaRuf 2012-02-13 14:36:43

0

你所展示的是使用情境的典型模式 - 按要求,类似于使用一个数据库连接。

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

如果你有这样的性能关键代码,这个开销真的很重要,你不应该使用实体框架,因为总会有一些开销,即使在一般情况下开销应该很小。我将开始专注于您的数据模型,以及底层的数据存储,这将对您的查询性能产生更大的影响。你有没有优化你的查询?你有没有把索引放在你需要的地方?你能否取消规范化数据以删除连接?

+0

我试图在同一个电话多次执行相同的查询,只有第一个需要很长时间,其他人几乎需要花费相同的时间才能完成SQL Management Studio!和我使用单例模式并设置静态ObjectContext时的行为相同。所以我认为这是当我声明一个新的ObjectContext的问题,不是吗? – MaRuf 2012-02-13 14:28:11

+0

您第一次初始化ObjectContext和MetaData。这就是为什么它第一次很慢。您的MetaData缓存每个AppDomain一次。 – 2012-02-13 14:32:34

+0

对不起,我不明白我在做什么错,每次我调用werbservice都会很慢,并且它会创建一个新的ObjectContext – MaRuf 2012-02-13 14:35:10

1

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

uow

uow and repository in EF

如果你觉得你有与您的查询的性能问题,还有就是你会重用你查询的可能性,我会建议你使用预编译的linq查询。你可以看看下面的链接,了解更多信息

precompiled linq julie lermann

precompiled linq