【问题标题】:Entity Framework Code-First is very slow实体框架代码优先非常慢
【发布时间】:2012-03-04 21:19:52
【问题描述】:

从广泛的谷歌搜索来看,我似乎不是第一个遇到这个问题的人,但我一直无法找到能够令人满意地解决它的人 - 我正在与旧数据库集成,我正在仅尝试与单个表集成(目前),但我对该模型的第一次查询大约需要 12 秒左右才能执行。不过,正如预期的那样,第二次通话几乎是即时的。

以下是我的 Entity Framework Code First 设置的全部内容:

public class PortalDatabase : DbContext
{
    public DbSet<User> Users { get; set; }

    public PortalDatabase():base("portalDatabase")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        User.ConfigureEntity(modelBuilder.Entity<User>());
    }
}

public class User
{
    public int ID { get; set; }

    public string FullName { get; set; }

    /// <summary>
    /// Internal representation of the IsDisabled flag. This should not be
    /// written to; use <see cref="IsDisabled"/> instead.
    /// </summary>
    internal byte IsDisabledInternal { get; set; }

    public bool IsDisabled
    {
        get { return Convert.ToBoolean(this.IsDisabledInternal); }
        set { this.IsDisabledInternal = Convert.ToByte(value); }
    }

    public int LoginAttempts { get; set; }

    public string EmailAddress { get; set; }

    public string Password { get; set; }

    internal static void ConfigureEntity(EntityTypeConfiguration<User> entity)
    {
        entity.ToTable("Users");

        entity.Property(model => model.ID)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
            .HasColumnName("UserID");

        entity.Property(model => model.FullName)
            .HasColumnName("UserName");

        entity.Property(model => model.IsDisabledInternal)
            .HasColumnName("AccountLocked");

        entity.Ignore(model => model.IsDisabled);

        entity.Property(model => model.LoginAttempts)
            .HasColumnName("LoginAttempts");

        entity.Property(model => model.EmailAddress)
            .HasColumnName("EmailAddress");

        entity.Property(model => model.Password)
            .HasColumnName("Password");
    }
}

此代码示例需要 8-12 秒才能执行:

    PortalDatabase database = new PortalDatabase();

    IEnumerable<User> users = from user in database.Users
                              where user.ID == 66
                              select user;

我知道这个问题与元数据生成有关,它只进行一次,according a comment from ScottGu“大大提高了性能”:

“代码优先”库使用与传统方法相同的底层 EF - 因此性能特征应该大致相同。 “代码优先”库还包含一个智能,以便为映射到/从数据库检索到的元数据被缓存 - 这样它只需要计算一次(这大大提高了性能)。

但是我所描述的表现是平均的吗?我无法想象 Entity Framework 团队可以接受花费 12 秒来执行一个简单的查询。我是不是误会他了?元数据缓存是否会在 IIS 应用程序池等生命周期内持续存在?这在某种程度上可能是可以接受的,尽管仍然不太理想。

如果我不首先使用代码,那么我可以use EdmGen.exe to generate my views,据我所知,这将使我的应用程序更快。首先使用代码开发我的模型时是否有等价物?

2012 年 2 月 14 日更新:感谢Pawel's post,我能够生成我的观点。不幸的是,这并没有改变创建新 PortalDatabase 实例的速度,这仍然需要相同的时间。我知道正在使用视图,因为我在构造函数中放置了一个断点,但这不会影响任何事情。

【问题讨论】:

  • 元数据缓存存在于 AppDomain 的整个生命周期中。元数据加载很慢,但对于这样一个简单的模型,12 秒真的很慢。
  • 我已将您的模型复制到控制台应用程序中,创建了空数据库(由 EF 自动创建)。第一个查询需要 1 秒,第二个查询立即返回。这 12 秒很奇怪……

标签: sql-server-2005 entity-framework


【解决方案1】:

要使用 CodeFirst 生成视图,请使用 EF Power Tools。在此处查看更多详细信息:http://blogs.msdn.com/b/adonet/archive/2011/05/18/ef-power-tools-ctp1-released.aspx

【讨论】:

  • 非常感谢!我能够生成视图,但不幸的是这并没有影响任何事情。你有什么进一步的想法吗?
  • 你确定什么需要时间?它只是第一个查询还是所有查询都很慢?如果它只是查询,它很可能是两件事之一 - 视图生成(对于小型模型不应发生)或创建数据库(如果不存在)。您是否看到数据库存在时的缓慢?另外,您是否尝试过手动连接到数据库?快吗?如果所有查询都发生这种情况 - 您可以尝试使用 Sql Profiler 查看执行查询需要多长时间?您是否还在使用任何更高级的映射,例如层次结构或实体拆分?
  • 如果你的模型像上面那样简单,你不应该期望 EF/CodeFirst 有太多的性能下降。对于这种模型,我会查看 network/db。
  • 好吧,我根本没有创建数据库,我现在正在连接到本地计算机上的 SQL 服务器实例。幸运的是,在对我的 WCF 服务的第一次请求之后,它所做的一切都会被缓存,因此我可以继续,而不必担心这会导致生产中出现问题。我真的希望我的单元测试能运行得更快。
猜你喜欢
  • 1970-01-01
  • 2016-10-17
  • 1970-01-01
  • 2017-09-01
  • 2014-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-24
相关资源
最近更新 更多