Ninject和WCF Web服务使实体框架变慢

时间:2019-05-15 07:19:45

标签: entity-framework wcf ninject

我有下一个设置:IIS中托管的WCF Web服务。实体框架6用于从数据库检索数据。 Web服务在Global.asax.cs中初始化,该服务继承自NinjectHttpApplication(因此我们将ninject用于依赖项注入)。在此NinjectHttpApplication中,在CreateKernel方法上,我们将EF DbContext绑定如下:

protected override IKernel CreateKernel()
{
    var kernel = new StandardKernel();
    kernel.Bind<DbContext>().To<MyCustomContext>().InTransientScope();
    return kernel;
}

然后,每次调用服务时,将在其构造器中按以下方式获取上下文:

_context = kernel.Get<DbContext>();    

然后,该服务从数据库中检索数据,如下所示:

data = _context.Set<TEntity>().Where(<whatever filter>);

话虽如此,我的问题是下一个:我有一个被多次调用的服务(带有多个联接的复杂而又长的查询),并且每次调用时,EF都会花很多时间来生成要发送的SQL我编码的Linq To Entities的结果。在数据库中执行查询不是什么(600毫秒),但是EF每次调用此服务都要花很长时间才能生成SQL。我怀疑这是由于kernel.Bind<DbContext>().To<MyContext>().InTransientScope()每次调用时都强迫EF创建DbContext的新实例。

我用UnitTests做过几次测试,其行为完全不同:如果您从同一个单元测试方法中多次实例化服务,然后调用它,那么EF仅需要很长时间才能第一次生成查询,然后从随后的调用中生成SQL不需要花费时间(相同的查询,但是具有不同的参数来过滤要检索的数据)。从单元测试来看,CreateKernel()当然仅在Initialize()方法中被调用过一次(就像在global.asax.cs中的Web服务中一样),所以我不知道是什么导致了如此巨大的延迟。我怀疑EF能够保留/缓存使用单元测试方法预编译的查询,但不能在实际的Web应用程序中保留。有什么线索吗?

请注意,Linq to Entities查询是参数化的(字符串和日期是参数)。

任何帮助非常感谢。

1 个答案:

答案 0 :(得分:0)

我发现您在InTransientScope中绑定了DbContext,这意味着每次您从ninject获取Dbcontext时,它将为您创建一个新的DbContext。

您可以考虑使用InThreadScope()而不是InTransientScope(),这意味着ninject在同一线程中时将返回相同的实例。

还有SingleTon作用域,这意味着总是返回相同的实例,但这会使dbcontext太大。