【问题标题】:Why is creating a MSSQL(Express) database with Entity Framework so slow?为什么使用 Entity Framework 创建 MSSQL(Express) 数据库这么慢?
【发布时间】:2016-10-10 04:45:09
【问题描述】:

我们正在开发一个可以管理多个客户端的 WPF 应用程序。对于每个客户端,我们需要一个单独的数据库(在同一个 SQL Server 实例中)。所以我们需要不止一次“创建数据库”。所有单独的客户端数据库都将具有相同的数据库结构。

我们使用实体框架版本 6.1.3、代码优先和 SQL Server 2014 Express 的本地安装。在我们的“真实”业务应用程序中,正确创建了一个包含大约 60 个表的新数据库,但性能不是很好。

为了找出问题,我编写了一个小示例程序,它在一个循环中创建 5 个数据库,每个数据库 1 个表。在我的 Dev-PC(Windows 10、i7-6700 3.40GHz、16 GB RAM)上,这 5 个数据库的执行时间约为 1 分钟(每个数据库为 11-12 秒)。调试应用的时候,看到在线等待很长时间

dbContext.Database.CreateIfNotExists();

在 SQL Server Profiler 中,我看到每个循环大约需要 10 秒,直到第一个条目到达。

知道时间在哪里浪费了吗?或者在实体框架中使用相同的 DbContext 创建多个数据库(> 20 个)的其他建议?

这里是我的示例应用程序的源代码:。

using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System;

namespace TestEnityFramework01.Model
{
    [Table("Table01")]
    public class Table01        {
        [Key]
        [Column("ID", Order = 0, TypeName = "int")]
        public int ID { get; set; }

        [Column("Number01", TypeName = "int")]
        public int Number01 { get; set; }

        [Column("Date01")]
        public DateTime? Date01 { get; set; }

        [StringLength(50)]
        [Column("Text01", TypeName = "nvarchar")]
        public string Text01 { get; set; }

        [Column("Amount01")]
        public decimal Amount01 { get; set; }

        [Column("Doule01")]
        public double Doule01 { get; set; }

        [Column("Bool01")]
        public bool Bool01 { get; set; }
    }
}

还有上下文:

using TestEnityFramework01.Model;
using System.Data.Entity;

namespace TestEnityFramework01.Context 
{
    class ContextA : DbContext
    {
    public DbSet<Table01> Tabel01 { get; set; }

    public ContextA()
        : base("ContextA")
    {
        // Don't create database automatically
        Database.SetInitializer<ContextA>(null);
    }

    public ContextA(string pConnectionString)
            : base(pConnectionString)
        {
            // Don't create database automatically
            Database.SetInitializer<ContextA>(null);

            this.Configuration.AutoDetectChangesEnabled = false;
            this.Configuration.LazyLoadingEnabled = false;
            this.Configuration.ValidateOnSaveEnabled = false;
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }
    }
}

测试程序循环生成五个数据库:

private void button_Click(object sender, RoutedEventArgs e)
{
    int _randomNumber = 0;

    for (int i = 1; i <= 5; i++)
    {
        // create random number between 1 and 100'000
        _randomNumber = new Random().Next(1, 100000);

        // concat the random number to the database name
        string _databaseName = "DatabaseCustomer" + _randomNumber.ToString();

           // the connection-string look like this:
           // "Data Source=MyPC\SQLEXPRESS;Initial Catalog=MyDatabaseName;User ID=MyUser;Password=MyPassword;Integrated Security=False;MultipleActiveResultSets=True;"            
        string  _connectionString = GetConnectionString(_databaseName);

        using (var dbContext = new ContextA(_connectionString))
        {
            // create the database
            dbContext.Database.CreateIfNotExists();
        }
    }
}

**** 2016 年 6 月 16 日更新**** 当我将数据库连接从 SQL-Server 2014 Express 切换到“SQL Server Compact Edition”时,所有 5 个数据库的创建时间大约为 1 或 2 秒。可能是我使用错误的连接字符串连接 sql-server 还是我的 SQL-Server 2014 Express 配置不正确?

【问题讨论】:

  • 出于好奇,您正在创建的 .mdf 和 .ldf 文件有多大?似乎默认值应该是 3 兆和 1 兆,但它们在您的测试用例中有多大?
  • .mdf 文件大小为 4'288 KB,.ldf 文件大小为 1072 KB。
  • 您确定Database.SetInitializer&lt;ContextA&gt;(null); 在您的代码中的位置吗?似乎天真地瞥了一眼您在初始化程序内部设置数据库初始化程序的代码,这似乎是错误的(可能是递归问题)。在在线示例中,我看到 setInitializer 发生在代码的配置部分。
  • 当 EF 尝试通过尝试连接来检查数据库是否存在时,我们看到了类似的 10 秒延迟,这是由 SqlClient 自己的连接弹性功能启动引起的。如果这导致您的方案出现延迟,您应该能够通过将 ConnectRetryCount=0 添加到连接字符串来改进。
  • 是的,你是对的。通过将 ConnectRetryCount=0 添加到连接字符串大约快十倍。非常感谢

标签: sql-server database performance ef-code-first entity-framework-6


【解决方案1】:

这是因为代码优先的方法创建了一个新的数据库并与之建立连接。

我认为您应该使用 sql 查询来创建数据库。

如果您愿意,我可以帮助您如何通过更好的 UI 和功能设计来做到这一点

请回复我的回答。

【讨论】:

  • 我不仅要创建一个新的数据库,还要创建基于我的代码优先模型的数据库结构(表)。而且,如果可能的话,使用实体框架。
  • 你可以在 txtFile 中写下你的结构并创建一个 sql Coomand 运行那个命令试试……我认为它会给你带来更好的性能。
  • 但如果你愿意,你可以只使用实体框架,这完全取决于你
猜你喜欢
  • 2016-04-20
  • 2015-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-04
相关资源
最近更新 更多