#c_sharp #entity_framework #entity_framework_core
Осваиваю Entity Framework Core, возникло непонимание работы с Navigation Properties
и в частности как должна работать Lazy load.
Модель Competition имеет связь многие к одну с моделями: Player (в каждом соревновании
по два участника), Arbitor, Tournament.
public class Competition
{
[Key]
public int CompetitionID { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int Player1ID { get; set; }
[Required]
public int Player2ID { get; set; }
[Required]
public int ArbitorID { get; set; }
[Required]
public int TournamentID { get; set; }
public Result? MatchResult { get; set; }
public virtual Player Player1 { get; set; }
public virtual Player Player2 { get; set; }
public virtual Arbitor Arbitor { get; set; }
public virtual Tournament Tournament { get; set; }
}
public class Player
{
public int PlayerID { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Country { get; set; }
[Required]
public int Age { get; set; }
public virtual ICollection Player1Competitions { get; set;}
public virtual ICollection Player2Competitions { get; set;}
}
public class Arbitor
{
[Key]
public int ArbitorID { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Country { get; set; }
[Required]
public int Seniority { get; set; }
public virtual ICollection Competitions { get; set; }
}
Модель Tournament опущена за ненадобностью при рассмотрении проблемы.
Так как Competition имеет два FK Player, явно прописал связи:
protected override void OnModelCreating (ModelBuilder modelBuilder)
{
modelBuilder.Entity ()
.HasOne ( m => m.Player1 )
.WithMany ( n => n.Player1Competitions )
.HasForeignKey ( m => m.Player1ID );
modelBuilder.Entity ()
.HasOne ( m => m.Player2 )
.WithMany ( n => n.Player2Competitions )
.HasForeignKey ( m => m.Player2ID );
}
Возникшие проблемы:
Насколько я понимаю, обозначая свойство как virtual, мы используем Lazy load. Но
тогда почему, если мне нужно получить запись Competition (со всеми свойствами), я должен
явно включать каждое свойство:
var competition = await _context.Competitions
.Include(c => c.Arbitor)
.Include(c => c.Player1)
.Include(c => c.Player2)
.Include(c => c.Tournament)
.SingleOrDefaultAsync(m => m.CompetitionID == id);
Если не прописываю Include, то свойства остаются null. Но ведь они должны подгружаться
самостоятельно при ленивой загрузке?
2.Схожая ситуация с коллекцией объектов, тоже объявленной как virtual. Разве при
ленивой загрузке коллекция не должна подгружаться без явного включения? Также насколько
я понимаю, при ленивой загрузке вложенные свойства должны также подгружаться (так для
каждого Competition должен подгрузиться необходимый Arbitor). Но явно включая коллекцию
и проходя по объектам, вложенные свойства остаются равны null. Как в таком случае подгружать
все вложенные свойства?
var player = await _context.Players
.Include ( s => s.Player1Competitions )
.Include ( s => s.Player2Competitions )
.SingleOrDefaultAsync ( m => m.PlayerID == id );
Ответы
Ответ 1
В EF сore фича lazy loading доступна с 2.1 Если очень хочется понять разницу между Eager - Lazy - Implicit, то делайте тренировочные проекты на EF 6. PS Я лично вообще считаю, что Lazy loading нужно отключить и не включать. Причина проста: явное лучше неявного. Вы можете управлять тем, что подключать и когда подключать, а не тянуть кучу лишнего из базы.
Комментариев нет:
Отправить комментарий