我有了下一个设置:托管在IIS中的WCF Web服务。Entity Framework6用于从DB检索数据。网络服务是在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发送到DB,这是我编码的Linq to Entities的结果。查询在数据库中的执行时间为零(600毫秒),但EF在每次调用此服务时都要花费很长时间才能生成SQL。我怀疑这是因为kernel.Bind<DbContext>().To<MyContext>().InTransientScope()强制EF在每次调用时创建DbContext的新实例。
我用UnitTests做了一些测试,其行为是完全不同的:如果您从相同的单元测试方法多次实例化服务并调用它,EF只在第一次生成查询时就会花费很长时间,那么从后续调用(相同的查询,但使用不同的参数来过滤要检索的数据)生成SQL不需要时间。从单元测试来看,CreateKernel()当然只在Initialize()方法中被调用一次(就像在global.asax.cs中的Web Service中一样),所以我不知道是什么导致了如此巨大的延迟。我怀疑EF能够使用单元测试方法保留/缓存预编译的查询,但不能在真正的web应用程序中使用。有什么线索吗?
请注意,Linq to Entities查询是参数化的(字符串和日期是参数)。
任何帮助都非常感谢。
发布于 2019-05-17 11:30:29
我发现你在InTransientScope中绑定了你的DbContext,这意味着每次你从一个对象中获取Dbcontext时,它都会为你创建一个新的DbContext。
您可以考虑使用InThreadScope()而不是InTransientScope(),这意味着当ninject在同一线程中时,它将返回相同的实例。
还有dbcontext作用域,这意味着总是返回相同的实例,但这会使SingleTon太大。
https://stackoverflow.com/questions/56143643
复制相似问题