Осваиваю 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<Competition> Player1Competitions { get; set;}
public virtual ICollection<Competition> 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<Competition> Competitions { get; set; }
}
Модель Tournament
опущена за ненадобностью при рассмотрении проблемы.
Так как Competition
имеет два FK Player
, явно прописал связи:
protected override void OnModelCreating (ModelBuilder modelBuilder)
{
modelBuilder.Entity<Competition> ()
.HasOne ( m => m.Player1 )
.WithMany ( n => n.Player1Competitions )
.HasForeignKey ( m => m.Player1ID );
modelBuilder.Entity<Competition> ()
.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 );
В EF сore фича lazy loading доступна с 2.1
Если очень хочется понять разницу между Eager - Lazy - Implicit, то делайте тренировочные проекты на EF 6.
PS Я лично вообще считаю, что Lazy loading нужно отключить и не включать. Причина проста: явное лучше неявного. Вы можете управлять тем, что подключать и когда подключать, а не тянуть кучу лишнего из базы.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
При создании проекта на С# студия автоматически вставляет следующий код:
В форме есть grdControl1 и gridview1 и gridview2Имеется контекстное меню с пунктом "Подробно"
Пробую использовать lazy loading entityframeworkСмотрю примеры с метанита
На сколько мне известно, запись ведется только через Master, а чтение возможно и из SlaveОднако встаёт такой вопрос: Если я подключился к Slave и знаю...