Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架慢速第一个数据库连接_C#_Entity Framework 6 - Fatal编程技术网

C# 实体框架慢速第一个数据库连接

C# 实体框架慢速第一个数据库连接,c#,entity-framework-6,C#,Entity Framework 6,我的应用程序(EF 6.2,代码优先)中的第一个数据库连接速度非常慢, 是否有方法修改我的DbContext部分的OnModelCreating: protected override void OnModelCreating(DbModelBuilder modelBuilder) { var typesToRegister = Assembly.GetExecutingAssembly() .GetTypes() .Where(

我的应用程序(EF 6.2,代码优先)中的第一个数据库连接速度非常慢, 是否有方法修改我的
DbContext
部分的
OnModelCreating

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
        var typesToRegister = Assembly.GetExecutingAssembly()
            .GetTypes()
            .Where(type => !String.IsNullOrEmpty(type.Namespace))
            .Where(type => type.BaseType != null
            && type.BaseType.IsGenericType
            && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));

        foreach (var type in typesToRegister)
        {
            dynamic configurationInstance = Activator.CreateInstance(type);
            modelBuilder.Configurations.Add(configurationInstance);
        }

        base.OnModelCreating(modelBuilder);
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
var typesToRegister=Assembly.getExecutionGassembly()
.GetTypes()
.Where(type=>!String.IsNullOrEmpty(type.Namespace))
.Where(type=>type.BaseType!=null
&&type.BaseType.IsGenericType
&&type.BaseType.GetGenericTypeDefinition()==typeof(EntityTypeConfiguration));
foreach(TypeStoreRegister中的变量类型)
{
dynamic configurationInstance=Activator.CreateInstance(类型);
modelBuilder.Configurations.Add(configurationInstance);
}
基于模型创建(modelBuilder);
}

在调试模式下,我发现这就是初始化连接需要几十秒的原因

您可以删除反射部分,只需手动输入类型即可。反射是一项缓慢的任务,你不能期望在使用反射的东西上有一个快速的体验,但因为这只是第一次连接,我个人不在乎,如果启动速度不是很关键的话。

第一个实体框架查询总是很慢,因为EF编译您的模型并在内存中生成映射视图

您可以使用EF Power工具预生成这些映射视图。这有一份文件

为了加载这些视图,您需要创建如下自定义DbConfiguration类:

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 
{
}
有关DbConfiguration的详细信息:

如果您的应用程序不在Azure SQL中运行,那么您可以做的另一件事是使用这样的CustomManifestTokenResolver

public class CustomManifestTokenResolver : IManifestTokenResolver
{
    public string ResolveManifestToken(DbConnection connection)
    {
        return "2012";
    }

}
为了使用它,您必须将它添加到DbConfiguration类中

public class MyDbConfiguration : DbConfiguration
{
    public MyDbConfiguration() : base()
    {
        var path = Path.GetDirectoryName(this.GetType().Assembly.Location);
        SetModelStore(new DefaultDbModelStore(path));
        SetManifestTokenResolver(new CustomManifestTokenResolver());
    }
}
启动期间的另一个性能问题是EF程序集的即时编译。您可以使用ngen来解决这个问题(假设您的程序集位于bin\release文件夹中)

%WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install .\bin\release\EntityFramework.dll
 %WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install .\bin\release\EntityFramework.dll
 %WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install .\bin\release\EntityFramework.SqlServer.dll
 %WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install .\bin\release\EntityFramework.SqlServer.dll
 %WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install .\bin\debug\EntityFramework.dll
 %WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install .\bin\debug\EntityFramework.dll
 %WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install .\bin\debug\EntityFramework.SqlServer.dll
 %WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install .\bin\debug\EntityFramework.SqlServer.dll
对于一般的EF性能问题,我有一个演示常见问题和解决这些问题的方法的平台

更新:添加了启动性能技巧

在我们的软件中,我们通常做的事情是在启动期间执行一个空查询。假设我们有一个名为
MyContext
的上下文和一个名为
Customers
的数据库集,我们会在启动期间编写如下内容:

using(var db = new MyContext())
{
   db.Customers.Where(x=> x.Id < 0).ToList();   // There are no negative Ids, so this will always be and empty list
}
使用(var db=new MyContext())
{
db.Customers.Where(x=>x.Id<0.ToList();//不存在负Id,因此这将始终是一个空列表
}

这将使您的初始化代码进入应用程序的启动阶段。因此,用户在系统中第一次真正查询时不会有缓慢的体验。您甚至可以异步执行此操作。您只需确保没有其他线程同时调用您的上下文,因为DbContext不是ThreadSafe.

“几十秒”?这似乎太过分了。你的上下文有多大,你有很多
DbSet
s吗?你在上面的代码的配置列表中添加了多少项?它们有什么不寻常的地方吗?我的意思是第一次连接需要一些时间…4个DbSet,4个模型,4个映射,这个模型继承自EntityTypeConfiguration。刚刚开始学习所有这些stuff…有时会有这样的拦截器。任何帮助都将不胜感激:)当应用程序启动时连接如何。。。类似“暖机应用程序”的东西?不过,应用程序启动速度会很慢,这并不能解决问题,而是掩盖了问题,让最终用户看不到。如果这个场景足够好,那么这是最简单的方法。如果你的程序是一个一分钟必须运行几次的控制台util,那就需要注意了。