[英]Lazy loading data in Entity Framework 6 with MySql not working
我正在使用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
意味着数据肯定已经在内存中实现了。 获得所需行为的唯一方法是使用支持延迟执行的接口,只有两种:
Expressions
构建的查询,用于在远程数据源(例如sql数据库)上触发查询。 Delegates
建立的,用于对内存中已有的数据集进行查询。 当使用First()
, FirstOrDefault()
, ToList()
或ToArray()
迭代数据时,使用这两种接口类型中的任何一种都会导致执行查询。
但是看到您只需要查询的区域名称是非常低效的。 您获取了整个DBZone
对象,但只使用了名称,我建议您仅获取名称:
return carrier.Zones.FirstOrDefault(z => z.Postcode == postcode).Select(z => z.ZoneName);
为此,您当然需要将carrier
保留为IQueryable
。
编辑:刚注意到“每次我打电话给运营商。区域运行大约需要8秒钟。”
这是延迟加载的预期行为。 当您访问数据时,将从数据库中获取数据=>运营商的数据库调用,访问区域时又对区域的数据库调用。 可以使用急切加载( Include
方法)在一次访问数据库中获取所有所需数据的情况下避免这种情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.