实体框架5性能不佳

2023-12-11

我有 5 个实体:

public class Album
{
    public int Id { get; set; }

    public string Title { get; set; }

    public virtual List<AlbumArtist> AlbumArtists { get; set; }
    public virtual List<Artist> Artists { get; set; }
    public virtual List<Genre> Genres { get; set; }
    public virtual List<Song> Songs { get; set; }

}

public class AlbumArtist
{
    public int Id { get; set; }

    public string Title { get; set; }

    public virtual List<Album> Albums { get; set; }
    public virtual List<Artist> Artists { get; set; }
    public virtual List<Genre> Genres { get; set; }
    public virtual List<Song> Songs { get; set; }
}

public class Artist
{
    public int Id { get; set; }

    public string Title { get; set; }

    public virtual List<AlbumArtist> AlbumArtists { get; set; }
    public virtual List<Album> Albums { get; set; }
    public virtual List<Genre> Genres { get; set; }
    public virtual List<Song> Songs { get; set; }
}

public class Genre
{
    public int Id { get; set; }

    public string Title { get; set; }

    public virtual List<AlbumArtist> AlbumArtists { get; set; }
    public virtual List<Album> Albums { get; set; }
    public virtual List<Artist> Artists { get; set; }
    public virtual List<Song> Songs { get; set; }
}

public class Song
{
    public int Id { get; set; }

    public string Title { get; set; }

    public virtual List<AlbumArtist> AlbumArtists { get; set; }
    public virtual List<Album> Albums { get; set; }
    public virtual List<Artist> Artists { get; set; }
    public virtual List<Genre> Genres { get; set; }
}

正如您所看到的,存在很多多对多关系。我填充我的实体,然后尝试以这种方式将它们保存到 DbContext:

_albumArtists.ForEach(delegate(AlbumArtist albumArtist)
{
    if (albumArtist.Id == 0)
    {
            _dbContext.Entry(entity).State = EntityState.Added;
            _dbContext.SaveChanges();
    }
    else
    {
            _dbContext.Entry(entity).State = EntityState.Modified;
            _dbContext.SaveChanges();
    }
});
...

或者这样:

_albumArtists.ForEach(delegate(AlbumArtist albumArtist)
{
    if (albumArtist.Id == 0)
    {
            _dbContext.Entry(entity).State = EntityState.Added;
    }
    else
    {
            _dbContext.AlbumArtists.State = EntityState.Modified;
    }
});
_dbContext.SaveChanges();
...

将我的实体保存到 DbContext 需要很长时间。我什至尝试执行以下操作:

Configuration.AutoDetectChangesEnabled = false;

但这没有帮助。顺便说一句,大约有 17,000 首歌曲和 1,700 张专辑。

怎么了???

请帮忙!

PS

这是我的完整代码:https://github.com/vjacheslavravdin/PsyTrance/blob/master/PsyTrance/Program.cs也许你可以建议如何简化它。

Thanks!


首先需要澄清几点:

对于基于批处理的操作,EF 并不比其他方法慢很多。在我的测试中,使用原始 SQL 命令可能会提高 50%,使用 SQL 批量复制可能会快 10 倍,但作为一般规则,EF 并不比比较方法慢很多(尽管通常被认为非常慢)。对于大多数应用程序,即使在批处理场景中,只要进行正确的调整,EF 也会给出合适的性能数字。 (请参阅我的文章:http://blog.staticvoid.co.nz/2012/3/24/entity_framework_comparative_performance and http://blog.staticvoid.co.nz/2012/8/17/mssql_and_large_insert_statements)

由于 EF 更改跟踪的方式,它有可能远远超过大多数人编写基于 SqlCommand 的插入语句的性能(查询计划、往返和事务有很多问题,这使得编写起来非常困难)最佳地执行批量插入语句)。我在这里向 EF 提出了这些补充(http://entityframework.codeplex.com/discussions/377636)但尚未实施。

您关闭自动检测更改的决定是完全正确的,每个带有检测更改的 .Add 或 .Attach 操作都会枚举跟踪图,因此,如果您在同一上下文中添加 17k 添加项,则需要枚举图 17000总共 17000 + 16999 + ...+ 2 + 1 = 144,500,000 个实体,难怪要花这么长时间,对吧? (请参阅我的文章:http://blog.staticvoid.co.nz/2012/5/7/entityframework_performance_and_autodetectchanges)

保存更改始终需要枚举跟踪图(它在内部调用检测更改),因此您的第一种方法会很慢,因为它实际上会执行与上面相同数量的跟踪调用。

第二种方法要好得多,但它仍然有一个相当大的缺陷,我认为这是双重的,首先,当您保存更改时,图形非常大(图形越大,跟踪时间呈指数级增长),其次,它会占用需要大量内存来一次性保存整个图,特别是考虑到 EF 存储每个实体的两个副本。

更好的方法是以块的形式保存图表。一些

//With Auto detect changes off.
foreach(var batch in batches)//keep batch size below 1000 items, play around with the numbers a little
{
    using(var ctx = new MyContext())//make sure you create a new context per batch.
    {
        foreach(var entity in batch){
             ctx.Entities.Add(entity);
        }
        ctx.SaveChanges();
    }
}

我预计您应该以 17-30 秒左右的时间来完成所有 17k 行。

通过使用原始 SQL 命令执行此操作,您可能可以将其缩短到 12-20 秒左右;

通过批量复制重新实现,您可能可以将其缩短到 2-5 秒

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实体框架5性能不佳 的相关文章

随机推荐

  • 在 mule esb 中从 JSON 中提取数组

    我正在使用 Mule 3 4 CE 并且我有一个通过 HTTP 传输的 JSON 数据 格式如下 People Details Name John Smith Email email protected Details Name Tim S
  • 在 scikit-learn 中保存新数据的特征向量

    为了创建机器学习算法 我创建了一个字典列表 并使用 scikit 的 DictVectorizer 为每个项目创建一个特征向量 然后 我使用部分数据进行训练 从数据集中创建了一个 SVM 模型 然后在测试集上测试该模型 您知道 这是典型的方
  • IE8 jQuery 淡入淡出

    HTML 标记 ul li class web span class info August 2007 a href http awebsite com visit a span a href assets image jpg class
  • Grails 控制器中操作和方法之间的差异

    据我所知 如果我想在控制器中创建一个动作 那么我可以通过以下方式完成 class My Controller def myAction println in my action 或者我可以通过以下方式创建它 class My Control
  • FragmentManager 替换使覆盖

    我正在使用 supportlib v4 来达到主从流程 问题 详细信息 片段的新实例覆盖第一个实例 创建的 xml 而不是替换它 我的活动布局是
  • 像 NSNumber 一样对 NSString stringWithFormat 进行装箱

    我们可以像这样创建一个 NSNumber NSNumber number NSNumber numberWithFloat 4 5 or NSNumber number 4 5 or NSNumber number 4 5 我知道我们可以使
  • 如果导入 iostream 为什么要使用命名空间

    我是 C 初学者 最近接触了 std 等命名空间 但是 如果像 cout 和 endl 这样的函数是在 iostream 头文件中定义的 为什么还要包含 std 命名空间呢 或者这些函数实际上是在 std 命名空间中定义的吗 如果是这样 那
  • 精度为 2 的小数的简单正则表达式

    精度为 2 的小数的正则表达式是什么 有效示例 123 12 2 56754 92929292929292 12 0 21 3 1 无效示例 12 1232 2 23332 e666 76 小数点可以是可选的 也可以包括整数 有效的正则表达
  • 如何从点列表中找到最近的坐标?

    假设我有一个 x y 坐标列表 如下所示 A 26 63 23 63 22 63 21 63 20 63 22 62 27 63 我有一个点的 x y 坐标 如下所示 leftbottom 0 238 现在 我想找到距离最近的点leftbo
  • Marshal.FreeHGlobal() 如何工作?

    我有一个基于 C 的 UI 它使用基于 C 的 DLL 我的要求是将一大块内存从 C 传递到 DLL DLL 将写入此内存缓冲区并将其传回 C 我已经使用 IntPtr 和全局内存函数来执行此操作 一切正常 问题是 如何验证 Marshal
  • 将 Inno Setup WizardForm.Color 转换为 RGB

    如果我尝试这个 Setup AppName MyApp AppVerName MyApp DefaultDirName pf MyApp DefaultGroupName MyApp OutputDir Code function Colo
  • 如何使用 Tidhttp 发出带有名为 xml 的参数的 Get 请求?

    我已成功使用 Delphi 2010 发出 http get 请求 但对于一项需要名为 xml 的参数的服务 请求失败并出现 HTTP 1 1 400 Bad Request 错误 我注意到调用相同的服务并省略 xml 参数是有效的 我尝试
  • 将文件内容重定向到php中的标准输入

    我有一个文件abc txt内容如下 hello hi good bad 现在 如何将文件的内容逐行重定向到php脚本的标准输入 这样当执行 php 脚本时 它可以通过以下任何命令收集输入 f fopen php stdin r line f
  • 视图状态 MAC 验证失败。应用程序由 Web Farm 托管,请确保 配置 [重复]

    这个问题在这里已经有答案了 Net 4 0框架 我在这个框架中制作了很多网站 但从未遇到过这样的错误 Validation of viewstate MAC failed If this application is hosted by a
  • 如何从最新版本的 Hyperledger Fabric 检索用户信息?

    我是 Hyperledger Fabric 的新手 在当前版本的 Hyperledger Fabric 中 在 chaincode go 中我找不到名为 ReadCertAttributes 的函数 有什么办法可以获取属性吗 从 Hyper
  • 返回文件或视图的方法

    我正在使用下面的 jquery 来调用GetFile方法 我想根据某些条件生成一个文本文件 这并不总是 始终生成一个文本文件 如果条件 True 生成文件 如果条件 False 返回主页 现在如果我回来 我只会得到一张空白页 我该如何写才能
  • Oracle PLSQL:xmltype.transform 与 xmltransform

    由于我们已将数据库从 11 2 0 2 0 移动到 11 2 0 4 0xmltype transform函数有特定的行为 问题是 之前它不能正常工作 它用开闭版本替换了所有标签 例如 它确实替换了 br with br 但我可以忍受 现在
  • 打印有序链表

    只是做了一些编辑 我尝试了你所说的 但它不起作用 所以我尝试了一些我更熟悉的东西 但它似乎无法正常工作 它奇怪地打印信息然后崩溃 例如 当我输入 9 8 7 6 5 4 3 2 1 然后输入 0 进行打印时 它会打印回给我 0 0 0 9
  • 列出“tkinter”中可用的字体系列

    In many tkinter那里有可用的示例 您可能会看到类似以下内容 canvas create text x y font Helvetica 12 text foo 但是 在您的计算机中运行时这可能不起作用 结果将完全忽略字体参数
  • 实体框架5性能不佳

    我有 5 个实体 public class Album public int Id get set public string Title get set public virtual List