c# - 使用 MySql 在 Entity Framework 6 中延迟加载数据不起作用

标签 c# mysql entity-framework entity-framework-6 code-first

我正在使用 MySql 开发代码优先的 EF6 项目。我已经设置了我的数据类,以便它们的相关数据对象应该被延迟加载,但它们每次被调用时似乎运行得非常慢。

这是我的实体类之一的示例:

[Table("Carrier")]
public class DBCarrier
{
    [Key]
    [Column("CarrierId")]
    public int carrierId { get; set; }

    [MaxLength(128), Required]
    public string CarrierName { get; set; }

    public virtual ICollection<DBDepot> Depots { get; set; }
    public virtual ICollection<DBZone> Zones { get; set; }
}

但是当我像这样在这个类的一个对象上调用 Zones 时(这一切都在一个语句中,但我把它分开来试图找出问题所在):

ICollection<DBZone> zones = carrier.Zones;
IEnumerable<DBZone> zones1 = zones.Where(x => x.Postcode == postcode);
return zones.Select(x => x.ZoneName).FirstOrDefault();

每次我调用 carrier.Zones 时,运行大约需要 8 秒。我认为将 zones 定义为 ICollection 会延迟数据库查询的执行。

最佳答案

ICollection 表示数据肯定已经在内存中具体化了。获得所需行为的唯一方法是使用支持延迟执行的接口(interface),只有两个:

  • IQueryable查询是使用 Expressions 构建的,用于在远程数据源(例如 sql 数据库)上触发查询。
  • IEnumerable查询是使用 Delegates 构建的,用于对内存中已有的数据集发起查询。

当您使用 First()FirstOrDefault()ToList( )ToArray()

但是看到您只需要区域的名称,您的查询效率很低。您获取了整个 DBZone 对象,但您只获取了名称,我建议只获取名称:

return carrier.Zones.FirstOrDefault(z => z.Postcode == postcode).Select(z => z.ZoneName);

为此,您当然需要将 carrier 保持为 IQueryable

编辑:刚刚注意到“每次我调用 carrier.Zones 时大约需要 8 秒才能运行。”

这是延迟加载的预期行为。当您访问数据时,数据将从数据库中获取 => 承运人的数据库调用,以及当您访问区域时对数据库的另一个调用。使用预先加载(Include 方法)一次访问数据库即可获取所有所需数据可以避免这种情况。

关于c# - 使用 MySql 在 Entity Framework 6 中延迟加载数据不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35357606/

相关文章:

entity-framework - EF6 扩展 TPH 层次结构(混合 TPH 和 TPT)

c# - 使用授权属性时的 Cors 策略错误

c# - ASP.net 按钮 onserverclick 仅在未定义 onclick 时有效

c# - 需要关闭所有正在运行的应用程序而不使用从 c# 应用程序注销的 Windows

mysql select into csv转义换行错误

php - php 中的 mysql 查询错误地评估为 true

entity-framework - Entity Framework 查看错误的数据库

c# - 拖放在 C# Winforms 应用程序中不起作用

Mysql从与另一个字段中的多个值匹配的行中找到不同的值

c# - ASP.NET 样板中的 DeleteRange 函数