我正在使用 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/