#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 ICollectionPlayer1Competitions { 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 нужно отключить и не включать. Причина проста: явное лучше неявного. Вы можете управлять тем, что подключать и когда подключать, а не тянуть кучу лишнего из базы.
Комментариев нет:
Отправить комментарий