与 ID 上的 .SingleOrDefault 相比,DbSet.Find 方法慢得离谱

2024-01-11

我有以下代码(数据库是SQL Server Compact 4.0):

Dim competitor=context.Competitors.Find(id)

当我对此进行分析时,Find 方法需要 300+ 毫秒才能从只有 60 条记录的表中检索竞争对手。

当我将代码更改为:

Dim competitor=context.Competitors.SingleOrDefault(function(c) c.ID=id)

然后只需 3 毫秒即可找到竞争对手。

竞争对手类别:

Public Class Competitor
    Implements IEquatable(Of Competitor)

    Public Sub New()
        CompetitionSubscriptions = New List(Of CompetitionSubscription)
        OpponentMeetings = New List(Of Meeting)
        GUID = GUID.NewGuid
    End Sub

    Public Sub New(name As String)
        Me.New()
        Me.Name = name
    End Sub

    'ID'
    Public Property ID As Long
    Public Property GUID As Guid

    'NATIVE PROPERTIES'
    Public Property Name As String

    'NAVIGATION PROPERTIES'
    Public Overridable Property CompetitionSubscriptions As ICollection(Of CompetitionSubscription)
    Public Overridable Property OpponentMeetings As ICollection(Of Meeting)
End Class

我定义了多对多关系CompetitionSubscriptions and OpponentMeetings使用流畅的 API。

的 ID 属性Competitorclass 是一个 Long,由 Code First 转换为数据表中具有主键的 Identity 列 (SQL Server Compact 4.0)

这里发生了什么??


Find calls DetectChanges内部,SingleOrDefault(或者通常任何查询)没有。DetectChanges是一项昂贵的操作,所以这就是原因Find速度较慢(但如果实体已加载到上下文中,它可能会变得更快,因为Find不会运行查询,而只是返回加载的实体)。

如果你想使用Find对于很多实体(例如在循环中),您可以像这样禁用自动更改检测(无法在 VB 中编写,因此使用 C# 示例):

try
{
    context.Configuration.AutoDetectChangesEnabled = false;
    foreach (var id in someIdCollection)
    {
        var competitor = context.Competitors.Find(id);
        // ...
    }
}
finally
{
    context.Configuration.AutoDetectChangesEnabled = true;
}

Now, Find不会打电话DetectChanges每次通话的速度应该尽可能快SingleOrDefault(如果实体已经附加到上下文,则速度更快)。

自动变化检测是一个复杂且有些神秘的主题。在这个由四部分组成的系列中可以找到详细的讨论:

(第 1 部分的链接,第 2、3 和 4 部分的链接位于该文章的开头)

http://blog.oneunicorn.com/2012/03/10/secrets-of-detectchanges-part-1-what-does-detectchanges-do/ http://blog.oneunicorn.com/2012/03/10/secrets-of-detectchanges-part-1-what-does-detectchanges-do/

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

与 ID 上的 .SingleOrDefault 相比,DbSet.Find 方法慢得离谱 的相关文章

  • .NET 5 EF Core SaveChangesAsync 因错误而挂起

    尽管这个问题有很多结果 但没有一个真正给我明确的答案 每次我尝试通过 AddAsync 和 SaveChangesAsync 方法插入错误数据 例如重复的主键 时 我都会看到以下日志 执行 DbCommand 失败 15 毫秒 我还在 SQ
  • 为什么没有主键的表是一个坏主意?

    我对数据建模非常陌生 根据微软的实体框架 不允许使用没有主键的表 这显然是一个坏主意 我试图找出为什么这是一个坏主意 以及如何修复我的模型 这样我就不会出现这个漏洞 我当前的模型中有 4 个表 User City HelloCity 和 R
  • 配置多个数据库Entity Framework 6

    在我的解决方案中 我有 2 个使用 Entity Framework 6 的项目 每个项目都指向不同的数据库 都使用相同的数据提供 SQL Server 我的解决方案中的第三个项目需要使用这两个数据库 我的问题是如何配置这些上下文 我尝试在
  • 使用 Entity Framework Core 2.0 更改或重命名列名称而不丢失数据

    我意识到我的一个列标题拼写错误 因此我在模型中更改了它并创建了一个新的迁移以将其更新到数据库中 一切都很完美 直到我意识到实际发生的情况是一个新列取代了现有列并删除了所有数据 碰巧的是 由于这是一个教程数据库 因此恢复数据并不重要 只需几分
  • 实体框架连接字符串定义

    我只是想知道 什么是实体框架连接字符串实际意思 喜欢 metadata res Models Model1 csdl res Models Model1 ssdl res Models Model1 msl provider System
  • 不同提供商的相同 EDMX 文件

    我正在开发一个项目 其中有一个本地数据库 SQL CE 在不存在与服务器的连接的情况下用作缓冲区 在服务器上我想使用相同的数据库布局 当然 我想使用服务器和客户端上可用的 Common dll 中的相同 EDMX 文件 在客户端中 我有一个
  • ADO.NET 池连接无法重用

    我正在开发一个 ASP NET MVC 应用程序 该应用程序使用 EF 6 x 来处理我的 Azure SDL 数据库 最近 随着负载的增加 应用程序开始进入无法再与 SQL 服务器通信的状态 我可以看到有 100 个到我的数据库的活动连接
  • 如果项目包含多个文件夹,如何使用 Add-Migration

    我想Add Migration使用我的 DbContext 但出现错误 The term add migration is not recognized as the name of a cmdlet function script fil
  • 如何从实体框架中的 .edmx 文件生成数据库?

    我不得不突然转而使用 Code First Entity Framework 4 1 一开始我对这个框架一无所知 但在过去的 8 个小时里 我现在对阅读博客和文章感到更加自在 特别是这个博客 http blogs msdn com b ad
  • 实体框架在多对多更新场景中附加问题

    我有一个场景 我希望更新电影实体及其与流派的多对多关系 导航属性Genres电影中包含存根Genre只包含的对象GenreID因为我想节省查询所有流派的数据库 请参阅下面的代码 其相当不言自明 问题是我需要将 存根 流派附加到上下文 以便
  • 在哪里使用 EF6 订阅 ObjectMaterialized?

    我正在尝试将我的上下文订阅到以下 OnjectMaterialized 事件this https stackoverflow com a 3756842 2835713 像这样 IObjectContextAdapter this Obje
  • 实体创建无用的 id 字段

    我有一个CrudRepository与两个实体 Problem 特征实体总是创建一个附加的id数据库中的字段但未选择正确的characteristic id要生成的字段JSON machine entity machine id name
  • EF 5.0 枚举未生成

    背景我在安装了 Net 4 5 的机器上使用 VS 2010 我读到这是就地安装 覆盖了 net 4 0 版本 我的项目仍然针对 4 0 而 4 5 选项不可用 但被告知没关系 因为 4 5 是就地安装 然后 我通过 nuget 安装了 E
  • 数据库优先方法和修改数据库模式

    我正在使用数据库优先方法使用实体框架 DbContext 构建 ASP NET MVC Web 应用程序 如果在某些情况下我需要修改数据库 例如添加新表或修改现有表 添加列或更改列数据类型 我应该 删除现有实体 edmx 和 tt 文件夹并
  • 同一数据库的多个实体框架

    我们可以在项目中为同一个数据库创建多个实体框架吗 我想为每个子系统创建实体框架 一些子系统具有共享表 这是可能的 您可以根据需要创建多个 EDMX 文件 但不建议这样做 因为 您不能查询不同模型中的多个表 定义边界将非常困难 因为大多数表都
  • 更改实体的可访问性

    我想建立一个内部实体 我已将实体 其标量属性和导航属性更改为内部 当我尝试构建它时出现此错误 错误 6036 EntityType 文件 具有 内部 可访问性 EntitySet 文件 具有具有 公共 可访问性的 get 属性 Entity
  • 如何使用实体框架设置连接字符串

    我将 EF6 与 MySQL 结合使用 并有一个用于多个数据库的模型 我希望能够在我的表单中设置连接设置 如何以编程方式设置模型的连接字符串 你应该使用EntityConnectionFactory这就是您所需要的 public strin
  • OnModelCreating 从未被调用

    我开始使用实体框架 问题是我的 OnModelCreating 方法从未被调用 这是我的上下文类 public class TestContext DbContext public TestContext base name TestDBC
  • 如何在种子实体框架版本 6.x 中通过 AddOrUpdate 方法插入身份[重复]

    这个问题在这里已经有答案了 我有一个具有身份列的实体 作为数据种子的一部分 我想对系统中的 标准数据 使用特定的标识符值 我不想禁用身份 只有我想在迁移种子中设置 IDENTITY INSERT ON 我的代码是 protected ove
  • LINQ 中的“from..where”或“FirstOrDefault”

    传统上 当我尝试从数据库中获取用户的数据时 我使用了以下方法 在某种程度上 DbUsers curUser context DbUsers FirstOrDefault x gt x u LoginName id string name c

随机推荐