加速实体框架4.2 POCO

kmp*_*kmp 5 .net c# performance entity-framework

我正在使用实体框架4.2,我有一个相当严重的性能问题.我正在使用POCO方法,继承自DbContext,这是一个解释问题的小样本:

我有一个有2个表的数据库 - A和B:

一个

  • AId(int - not null - identity - primary key)
  • 名称(nvarchar(50) - 非null)

  • BId(int - not null - identity - primary key)
  • SomeValue(int - not null)
  • AId(int - not null - 连接到表A中的AId的外键)

A中有一行(1,'Test'),B有6000行(SomeValue只是0到5999之间的数字) - 所有这些都通过外键列引用A行.

我从数据库创建一个edmx并关闭代码生成.然后我创建以下类:

public class DatabaseContext : DbContext
{
    public DatabaseContext(string name) : base(name)
    {
        Configuration.AutoDetectChangesEnabled = false;
        As = Set<A>();
        Bs = Set<B>();
    }

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

public class A
{
    public virtual int AId { get; set; }
    public virtual string Name { get; set; }
    public virtual ICollection<B> Bs { get; private set; }

    public void AddB(B b)
    {
        if (b == null)
        {
            throw new ArgumentNullException("b");
        }

        if (Bs == null)
        {
            Bs = new List<B>();
        }

        if (!Bs.Contains(b))
        {
            Bs.Add(b);
        }

        b.A = this;
    }
}

public class B
{
    public virtual int BId { get; set; }
    public virtual A A { get; set; }
    public virtual int SomeValue { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在我只需执行以下操作:

var ctx = new DatabaseContext("ScalabilityTestEntities");
var a = ctx.As.FirstOrDefault();
a.Bs.Add(new B { SomeValue = 987 });
Run Code Online (Sandbox Code Playgroud)

最后一行(我添加一个新的B)在我的四核,4gb RAM 64位Windows 7机器上占用6秒的区域,该机器在本地运行数据库.

真正糟糕的是它似乎会以指数方式降低某些因素,因为如果你将B中的行数加倍,则需要接近20秒!

我真的很感激任何使这种情况更快发生的提示.非常感谢!

Mar*_*ill 4

导航属性的世界可能是一个痛苦的世界。我们基本上不得不逐步淘汰它们的使用,因为它们会在背后造成如此多的性能问题(特别是当您附加和分离实体时,但这是一个不同的故事)。

发生的情况是,当您访问 a.Bs 时,它会加载该 A 的所有 B。

在这种特定情况下,如果您实际上不需要 B 的完整列表,而只想添加一个新列表,那么最好简单地创建一个 B 并将其 AId 设置为 A 的 ID。