Asp.net mvc Entity Framework 6.2非常慢的首次启动和eInteractiveView

Asp.net mvc Entity Framework 6.2非常慢的首次启动和eInteractiveView,asp.net-mvc,entity-framework,entity-framework-6,linq-to-entities,Asp.net Mvc,Entity Framework,Entity Framework 6,Linq To Entities,这个话题已经在stackoverflow和许多其他博客上广泛讨论过了,提出这个问题的原因是我观察到这个话题在大多数3到5年前的帖子中讨论过,而我们现在已经有了EF 6.2版本,我希望这可能已经有了更新(你们会发现更多的原因) 我的应用程序至少有25个模型(表),以MySQL作为数据库,模型和关系在OnModelCreating中配置,网站托管在godaddy上,我无法很好地访问IIS配置等 页面加载时间 第一页加载:65到70秒 第二页加载:1到3秒 再次延迟10分钟后,加载页面需要70秒。

这个话题已经在stackoverflow和许多其他博客上广泛讨论过了,提出这个问题的原因是我观察到这个话题在大多数3到5年前的帖子中讨论过,而我们现在已经有了EF 6.2版本,我希望这可能已经有了更新(你们会发现更多的原因)

我的应用程序至少有25个模型(表),以MySQL作为数据库,模型和关系在OnModelCreating中配置,网站托管在godaddy上,我无法很好地访问IIS配置等

页面加载时间

  • 第一页加载:65到70秒
  • 第二页加载:1到3秒
再次延迟10分钟后,加载页面需要70秒。 请注意,我在不同的环境中测试了它,比如使用不同的互联网连接。 页面上没有图片,测试页面只有5行数据和两列(调用简单方法db.test.ToList();)

在搜索互联网时,我发现这是EF的常见问题,所以我尝试修复它,同时从帖子和网站上寻求帮助

在这次修复之后

  • 第一页加载:64到67秒
  • 第二页加载:1到3秒

    // DbConfiguration constructor
    public MyDbConfiguration
    {
         var path = Path.GetDirectoryName(this.GetType().Assembly.Location);
         SetModelStore(new DefaultDbModelStore(path));
    }
    
    // DbContext
    private static DbMappingViewCacheFactory viewCacheFactory;
    
    private static DbMappingViewCacheFactory ViewCacheFactory
    {
        get
        {
            if (viewCacheFactory == null)
            {
                var path =ConfigurationManager.AppSettings[GlobalContextConfig.EFCacheFolder];
                viewCacheFactory=new FileViewCacheFactory(path+"Budget.Context.MyDbContext.xml");
            }
            return viewCacheFactory;
        }
    }
    
    
    public MyDbContext()
        : base("name=MySqlConnectionString")
    {
         // In case i need to update xml for now i delete the old file manually 
        InteractiveViews.SetViewCacheFactory(this, ViewCacheFactory);
    
        Database.SetInitializer<MyDbContext>(null);
    
        this.Configuration.ProxyCreationEnabled = false;
        this.Configuration.LazyLoadingEnabled = false;
        this.Configuration.AutoDetectChangesEnabled = false;
        this.Configuration.ValidateOnSaveEnabled = false;
    }
    
    //DbConfiguration构造函数
    公共数据库配置
    {
    var path=path.GetDirectoryName(this.GetType().Assembly.Location);
    SetModelStore(新的DefaultDbModelStore(路径));
    }
    //DbContext
    私有静态DbMappingViewCacheFactory viewCacheFactory;
    私有静态DbMappingViewCacheFactory ViewCacheFactory
    {
    得到
    {
    if(viewCacheFactory==null)
    {
    var path=ConfigurationManager.AppSettings[GlobalContextConfig.EFCacheFolder];
    viewCacheFactory=新文件viewCacheFactory(路径+“Budget.Context.MyDbContext.xml”);
    }
    返回工厂;
    }
    }
    公共MyDbContext()
    :base(“name=MySqlConnectionString”)
    {
    //如果我现在需要更新xml,我会手动删除旧文件
    InteractiveViews.SetViewCacheFactory(这是ViewCacheFactory);
    Database.SetInitializer(null);
    this.Configuration.ProxyCreationEnabled=false;
    this.Configuration.LazyLoadingEnabled=false;
    this.Configuration.AutoDetectChangesEnabled=false;
    this.Configuration.ValidateOnSaveEnabled=false;
    }
    
它得到了改进,但还不够,我想知道这些问题是否在EF 6.2.0中得到了更新,或者修复方法是否发生了变化,或者我做错了什么/应该检查一下

我还安装了EF 6.1.X并通过右键单击Contaxt文件并在manu中选择Entity Framework>Generate View来生成视图

结果:

  • 第一页加载:40到50秒
  • 第二页加载:0到1.5秒
这非常惊人,EF6.1.X比EF6.2快得多

生成并部署为发布包,debug=false

出于测试目的,我还上传了没有实体框架的asp.net应用程序,第一次加载需要8到13秒,第二次加载不到1秒

我想知道这些问题是否在EF 6.2.0中更新,或者修复方法是否改变,或者我做错了什么/应该检查什么

答案是肯定的

EF 6.2引入了模型缓存

public class MyDbConfiguration : DbConfiguration
{
    public MyDbConfiguration() : base()
    {
        var path = Path.GetDirectoryName(this.GetType().Assembly.Location);
        SetModelStore(new DefaultDbModelStore(path));
    }
}

[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContextContext : DbContext 
{
}

您可以在此处了解更多信息:

我想您已经阅读了性能注意事项:

我个人也在与这些问题作斗争。我求助于。和b)我创建了一个热身机制。还可以选择预编译查询,这可能会有所帮助

预热机制在应用程序开始时在一个单独的线程上运行。在那里,它对数据库执行一个非常简单的请求,这将强制创建模型,并“触发”所有查询的初始启动延迟。在该查询运行后(需要几秒钟),将设置一个标志。所有其他操作在运行前等待设置标志。特别是在多线程场景中,这会有很大帮助

我发现启动延迟是每个线程创建的。这意味着,如果延迟是2秒,运行3个线程,这些线程都创建了一个上下文并尝试运行一些linq,那么让整个应用程序等待6秒

注意,通过创建自定义查询,必须返回要创建的实体的所有字段

    var blogs = context.Blogs.SqlQuery("SELECT * FROM dbo.Blogs").ToList(); //works
    var blogs = context.Blogs.SqlQuery("SELECT [id] FROM dbo.Blogs").ToList(); //Does not.

我还没有完全测试过这个问题,所以需要一些时间来测试。这只是一个提示。

是的,我也做过这种配置,正如我在文章中提到的,是否有第三方工具来处理缓存或二级缓存?答案取决于您所说的“处理缓存”是什么意思。缓存查询?缓存模型?这是关于缓存模型的,他们可能有一个,但我不知道,你有没有找到解决这个问题的方法?我也有同样的问题,最初的启动速度非常慢。如果你的网站是像godaddy这样的第三方网站,那真的很难,我还在努力。如果您在本地托管,则不会花费太长时间。将上下文划分为多个上下文,如销售、客户等。禁用调试,不使用延迟加载,关闭自动检测更改,有许多帖子描述了不同的内容,感谢分享,我的场景变得更加复杂,当我在godaddy托管的网站上工作时,我没有足够的权限访问IIS配置,此时ASP.Net变成了垃圾,速度非常慢。使用自定义查询对我来说没有意义,那么为什么我要使用实体框架呢?我最好建立自己的数据访问框架,这只需要一次努力。从我的经验中我了解到,ASP.Net只适合本地解决方案,其他领域可能不在其目标范围内。由于EF Core也有同样的问题,这意味着他们不会去解决它。“使用自定义查询对我来说毫无意义,那个么我为什么要使用实体框架?”当然是为了提高速度!您正在删除另一层,同时仍在代码中保留有用的对象。更多的是关于不