【问题标题】:Entity Framework very slow performance when get the navigation property获取导航属性时,实体框架的性能非常慢
【发布时间】:2015-11-15 07:21:09
【问题描述】:

只有两个最简单的表 A 和 B,其中 A 包含许多 B,如下表所示。然后我创建B的20000条记录并将它们添加到一个A中。现在,如果我重新启动程序并执行if(a.Bs==null)代码行如下,它将花费120秒!!

我认为 20000 条记录对 EF 来说不是什么大事,那么有没有人可以帮助我解决这个性能问题?

public class A
{
    [Key]
    public int EntityId { get; set; }
    public virtual ICollection<B> Bs { get; set; }
}

public class B
{
    [Key]
    public int EntityId { get; set; }
    public virtual A A { get; set; }
}

///////////上下文为:////////////////////

public class MyDbContext : DbContext
{
    public MyDbContext()
        : base("MyDbContext")
    {
    }

    public DbSet<A> As { get; set; }
    public DbSet<B> Bs { get; set; }
}

//////////性能问题如下/////////////

using (var db = new MyDbContext())
{
    var a = db.As.First();

    if (a.Bs == null)\\This line will cost about 120 seconds!!!!!!
    {}
}

【问题讨论】:

  • 可能是因为您没有任何索引并且调用 a.Bs 是在告诉 EF 获取与 A 相关的每个 B。
  • 谢谢,但实际上,EF 会自动在表 B 中创建 IX_A_EntityId。所以,这似乎不是原因。
  • 我查看了 SQL Profiler。只执行了一条 sql,只需几毫秒。
  • 最大的开销是创建proxyClass造成的。当我写下面的代码行时: db.Configuration.ProxyCreationEnabled = false;它会立即返回,但 a.Bs 为空。那么,谁能帮帮我?
  • 你可以尝试使用if (!a.Bs.Any()) - 更快吗?

标签: performance entity-framework navigation-properties


【解决方案1】:

在您的代码中,当您访问 a.Bs 时,所有集合都会被物化(通过惰性加载器),并且 20.000 条记录的物化需要很多时间。另外,我认为 a.Bs 永远不会为空。
如果您不需要将 Bs 加载到内存中,您可以找到另一种方法来进行检查,即

if (a.Bs.Count() == 0) {}

【讨论】:

  • 谢谢,但如果数据库中没有 B,a.Bs 将为空。
  • 而 if (a.Bs.Count() == 0) {} 也将花费与 a.Bs.Any() 或 a.Bs.FirstOrDefault() 相同的时间,因为我们尝试获得学士学位。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-29
  • 2016-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多