Страницы

Поиск по вопросам

пятница, 14 февраля 2020 г.

Entity Framework Core и Lazy Load

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

Комментариев нет:

Отправить комментарий