实体框架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性能不佳 的相关文章

  • 为什么 int8_t 和用户通过 cin 输入显示奇怪的结果[重复]

    这个问题在这里已经有答案了 一小段代码让我发疯 但希望你能阻止我跳出窗外 看这里 include
  • 如何将非静态类成员“std::bind”绑定到 Win32 回调函数“WNDPROC”?

    我正在尝试将非静态类成员绑定到标准WNDPROC http msdn microsoft com en us library ms633573 aspx功能 我知道我可以通过将类成员设为静态来简单地做到这一点 但是 作为一名 C 11 ST
  • 提交后禁用按钮

    当用户提交付款表单并且发布表单的代码导致 Firefox 中出现重复发布时 我试图禁用按钮 去掉代码就不会出现这个问题 在firefox以外的任何浏览器中也不会出现这个问题 知道如何防止双重帖子吗 System Text StringBui
  • 在 DataView 的 RowFilter 中选择 DISTINCT

    我试图根据与另一个表的关系缩小 DataView 中的行范围 我使用的 RowFilter 如下 dv new DataView myDS myTable id IN SELECT DISTINCT parentID FROM myOthe
  • 在 LINQ 中按 Id 连接多表和分组

    我想按categoryId显示列表产品的名称组 这是我的代码 我想要我的视图显示结果 Desktop PC HP Red PC Dell Yellow PC Asus Red SmartPhone Lumia 720 Blue 我的组模型
  • 错误:表达式不产生值

    我尝试将以下 C 代码转换为 VB NET 但在编译代码时出现 表达式不产生值 错误 C Code return Fluently Configure Mappings m gt m FluentMappings AddFromAssemb
  • 使用接口有什么好处?

    使用接口有什么用 我听说它用来代替多重继承 并且还可以用它来完成数据隐藏 还有其他优点吗 哪些地方使用了接口 程序员如何识别需要该接口 有什么区别explicit interface implementation and implicit
  • 由 IHttpClientFactory 注入时模拟 HttpClient 处理程序

    我创建了一个自定义库 它会自动为依赖于特定服务的 Polly 策略设置HttpClient 这是使用以下方法完成的IServiceCollection扩展方法和类型化客户端方法 一个简化的例子 public static IHttpClie
  • 将 Word 文档另存为图像

    我正在使用下面的代码将 Word 文档转换为图像文件 但是图片显得太大 内容不适合 有没有办法渲染图片或将图片保存到合适的尺寸 private void btnConvert Click object sender EventArgs e
  • qdbusxml2cpp 未知类型

    在使用 qdbusxml2cpp 程序将以下 xml 转换为 Qt 类时 我收到此错误 qdbusxml2cpp c ObjectManager a ObjectManager ObjectManager cpp xml object ma
  • 为什么调用非 const 成员函数而不是 const 成员函数?

    为了我的目的 我尝试包装一些类似于 Qt 共享数据指针的东西 经过测试 我发现当应该调用 const 函数时 会选择它的非 const 版本 我正在使用 C 0x 选项进行编译 这是一个最小的代码 struct Data int x con
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • 使用自定义堆的类似 malloc 的函数

    如果我希望使用自定义预分配堆构造类似 malloc 的功能 那么 C 中最好的方法是什么 我的具体问题是 我有一个可映射 类似内存 的设备 已将其放入我的地址空间中 但我需要获得一种更灵活的方式来使用该内存来存储将随着时间的推移分配和释放的
  • C#:帮助理解 UML 类图中的 <>

    我目前正在做一个项目 我们必须从 UML 图编写代码 我了解 UML 类图的剖析 但我无法理解什么 lt
  • 等待进程释放文件

    我如何等待文件空闲以便ss Save 可以用新的覆盖它吗 如果我紧密地运行两次 左右 我会得到一个generic GDI error
  • WebSocket安全连接自签名证书

    目标是一个与用户电脑上安装的 C 应用程序交换信息的 Web 应用程序 客户端应用程序是 websocket 服务器 浏览器是 websocket 客户端 最后 用户浏览器中的 websocket 客户端通过 Angular 持久创建 并且
  • 我的班级应该订阅自己的公共活动吗?

    我正在使用 C 3 0 遵循标准事件模式我有 public event EventHandler
  • 如何从 ODBC 连接获取可用表的列表?

    在 Excel 中 我可以转到 数据 gt 导入外部数据 gt 导入数据 然后选择要使用的数据源 然后在提供登录信息后 它会给我一个表格列表 我想知道如何使用 C 以编程方式获取该列表 您正在查询什么类型的数据源 SQL 服务器 使用权 看
  • 当从finally中抛出异常时,Catch块不会被评估

    出现这个问题的原因是之前在 NET 4 0 中运行的代码在 NET 4 5 中因未处理的异常而失败 部分原因是 try finallys 如果您想了解详细信息 请阅读更多内容微软连接 https connect microsoft com
  • 当我使用 OpenSSL1.1.0g 根据固定的 p 和 g 值创建 Diffie Hellman 密钥协议密钥时,应该执行哪些检查?

    您好 我尝试通过这段代码使用修复 p 和 g 参数来制作 Diffie Hellman Keysanswer https stackoverflow com a 54538811 4706711 include

随机推荐

  • 在 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