![](/img/trans.png)
[英]Entity Framework Core Eager Loading Then Include on a collection
[英].NET Core - Entity Framework - Unexpected Behaviour with Eager Loading Include()
如果运行以下查询, CityTranslation.IdFkLanguageNavigation
得到以下结果, CityTranslation.IdFkLanguageNavigation
将为null
。 另一方面,将填充CityTranslation.IdFkCityNavigation
。 考虑到它们都处于相同的层次结构级别。
var data = await _context.City
.Include(x => x.CityTranslation)
.Include(c => c.IdFkCountryNavigation)
.ToListAsync();
我试过在.Include(x => x.CityTranslation)
ThenInclude()
之后使用ThenInclude()
,但是它不允许我使用Language属性。
通过下面的查询,我确实得到了一些意外的结果。 一旦我通过data2
调试,突然我的第一个查询结果中的Language
navigation属性就被填充了!
仅当我在第二个查询上调用ToList()
,此方法才有效,否则仍然不会被填充。 我必须假设数据是在整个EF上下文中共享的,但是如何在不向数据库发送第二个查询的情况下利用这种行为呢? 这种行为令我非常震惊,希望您能提供任何参考或解释。
var data = await _context.City
.Include(x => x.CityTranslation)
.Include(c => c.IdFkCountryNavigation).ToListAsync();
var data2 = _context.CityTranslation.Include(c => c.IdFkLanguageNavigation).ToListAsync();
我正在使用Microsoft.EntityFrameworkCore.SqlServer
版本1.1.2
public partial class City
{
public City()
{
CityTranslation = new HashSet<CityTranslation>();
}
public int IdPkCity { get; set; }
public string Id { get; set; }
public string Code { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
public string TimeZone { get; set; }
public string Uri { get; set; }
public string Name { get; set; }
public string Language { get; set; }
public int? IdFkCountry { get; set; }
public virtual ICollection<CityTranslation> CityTranslation { get; set; }
public virtual Country IdFkCountryNavigation { get; set; }
public partial class CityTranslation
{
public int IdPkCityTranslation { get; set; }
public string Translation { get; set; }
public int IdFkCity { get; set; }
public int IdFkLanguage { get; set; }
public virtual City IdFkCityNavigation { get; set; }
public virtual Language IdFkLanguageNavigation { get; set; }
}
public partial class Language
{
public Language()
{
AirportTranslation = new HashSet<AirportTranslation>();
CityTranslation = new HashSet<CityTranslation>();
CountryTranslation = new HashSet<CountryTranslation>();
}
public int IdPkLanguage { get; set; }
public string Name { get; set; }
public string Code { get; set; }
public virtual ICollection<AirportTranslation> ATranslation{ get; set; }
public virtual ICollection<CityTranslation> CTranslation { get; set; }
public virtual ICollection<CountryTranslation> C2Translation { get; set; }
}
这将起作用,只需粘贴此即可。
// Hits the database only once
var data = await _context.City
.Include(x => x.CityTranslation)
.ThenInclude(x => x.IdFkLanguageNavigation)
.ToListAsync();
现在,关于第二个查询为什么加载第一个查询的“ Language
导航属性的原因,您必须研究EntityFramework的整体工作原理,并仔细阅读显式加载。
这是显式加载的示例。
// Hits the database once.
var data = await _context.City
.Include(x => x.CityTranslation)
.ToListAsync();
var cityTranslationIds = data.Select(x => x.CityTranslation.IdPkCityTranslation);
// Hits the database the second time.
// Language navigation property will be loaded onto the data variable above
_context.Language
.Where(x => cityTranslateIds.Contains(x.IdPkLanguage))
.Load();
// Your second query, what you did here is essentially the same as the above's Load(),
// but the Load() is better suited for your intention.
var data2 = await _context.CityTranslation
.Include(c => c.IdFkLanguageNavigation)
.ToListAsync();
根据情况,您需要在渴望加载和显式加载之间进行选择,以实现最佳性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.