Как получить иерархию данных для ViewModels из трех таблиц с помощью EF?

Запутался и не могу догнать как сделать)

Есть некие модели представления, и под них я сделал модели и сделал настройку связей (вроде правильно, всё ниже).

Не могу понять как получить данные из бд с помощью EF по трём таблицам и замапить в модели представления используя репозиторий. Как это всё собрать вместе?

Модели представления:

public class EducationalLevelPreparationVM
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public string LevelName { get; set; } = string.Empty;
    public ObservableCollection<EducationalDirectionTrainingVM> DirectionsTraining { get; set; } = new();
}

public class EducationalDirectionTrainingVM
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public string DirectionCode { get; set; } = string.Empty;
    public string DirectionName { get; set; } = string.Empty;
    public ObservableCollection<EducationalProfileVM> EducationalProfiles { get; set; } = new();
}

public class EducationalProfileVM
{
    public Guid Id { get; set; } = Guid.NewGuid();
    public string ProfileCode { get; set; } = string.Empty;
    public string ProfileName { get; set; } = string.Empty;
    public ObservableCollection<string> FormsOfTraining { get; set; } = new();
}

Модели:

public class EducationalLevelPreparation
{
    public Guid Id { get; set; }
    public string LevelName { get; set; } = string.Empty;
}

public class EducationalDirectionTraining
{
    public Guid Id { get; set; }
    public string DirectionCode { get; set; } = string.Empty;
    public string DirectionName { get; set; } = string.Empty;

    public Guid EducationalLevelPreparationId { get; set; }
    public EducationalLevelPreparation EducationalLevelPreparation { get; set; }
}

public class EducationalProfile
{
    public Guid Id { get; set; }
    public string ProfileCode { get; set; } = string.Empty;
    public string ProfileName { get; set; } = string.Empty;

    public Guid EducationalDirectionTrainingId { get; set; }
    public EducationalDirectionTraining EducationalDirectionTraining { get; set; }
}

Настроенные связи:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<EducationalLevelPreparation>()
        .HasMany<EducationalDirectionTraining>()
        .WithOne(x => x.EducationalLevelPreparation)
        .HasForeignKey(x => x.EducationalLevelPreparationId)
        .OnDelete(DeleteBehavior.Cascade);


    modelBuilder.Entity<EducationalDirectionTraining>()
        .HasMany<EducationalProfile>()
        .WithOne(x => x.EducationalDirectionTraining)
        .HasForeignKey(x => x.EducationalDirectionTrainingId)
        .OnDelete(DeleteBehavior.Cascade);
}

Суть:

Уровни имеют несколько направлений, а направления имеют несколько профилей. (Связи вроде правильные)

Данные отображаются в TreeView, привязанный к

public ObservableCollection<EducationalLevelPreparationVM> Levels { get; set; } = new();

(там все уровни показываются, если я статично добавлю всю иерархию от руки)

А как с помощью EF, получить всю иерархию данных и засунуть в

public ObservableCollection<EducationalLevelPreparationVM> Levels { get; set; } = new();

вызывая метод Read() прокинутого репозитория.

Какая там должна быть последовательность действий?


Ответы (1 шт):

Автор решения: Voenkomat

Разобрался вроде как, если можно было как то лучше то подскажите)

  1. Во ViewModelях изменил коллекции на ICollection типы.

  2. В модели добавил эти же ICollection типы.

  3. Код получения данных и маппинг:

    public List<EducationalLevelPreparationVM> Read()
    {
     using (var db = new DataContext())
     {
         return db.SettingLevels.Select(level => new 
    EducationalLevelPreparationVM
         {
             Id = level.Id,
             LevelName = level.LevelName,
             DirectionsTraining = level.DirectionsTraining.Select(direction => new EducationalDirectionTrainingVM
             {
                 Id = direction.Id,
                 DirectionCode = direction.DirectionCode,
                 DirectionName = direction.DirectionName,
                 EducationalProfiles = direction.EducationalProfiles.Select(profile => new EducationalProfileVM
                 {
                     Id = profile.Id,
                     ProfileCode = profile.ProfileCode,
                     ProfileName = profile.ProfileName
                 }).ToList()
             }).ToList()
         }).ToList();
     }
     }
    

Что-то типа такого)

→ Ссылка