Включить сущность общего свойства списка в ASP.NET EntityFramework Core

У меня есть отношение «многие ко многим» между родителями и дочерними элементами, использующее таблицу отношений, потому что эти отношения еще не поддерживаются автоматически в EF Core:

class Parent{
    [Key]
    public int Id{get;set;}
    public List<ParentChild> ParentChilds{get;set;}
}

class Child{
    [Key]
    public int Id{get;set;}
    public List<ParentChild> ParentChilds{get;set;}
}

class ParentChild{
    public int ParentId{get;set;}
    public Parent Parent{get;set;}
    public int ChildId{get;set;}
    public Child Child{get;set;}
}

Для редактирования родителя мне нужно получить ВСЕ его дочерние элементы. Похоже на работу для Include()

var db = new MyDbContext();
var parentWithChilds = db.Parents.Include(p => p.ParentChilds)
    .FirstOrDefault(p => p.Id == 1);

Это дало мне список ParentChild точек. Но объект Child ParentChild не загружается автоматически, поэтому у меня есть только идентификатор дочернего элемента, но не сам дочерний объект, который мне нужен. Я нашел ThenInclude, который, похоже, предназначен для таких случаев и из таких примеров, как этот я сделал следующее:

var parentWithChilds = db.Parents.Include(p => p.ParentChilds)
    .ThenInclude(p => p.Select(x => x.Child))
    .FirstOrDefault(p => p.Id == 1);

Но выдает исключение:

Выражение свойства 'p => {from ParentChild x in p select [x].Child => FirstOrDefault()}' недопустимо. Выражение должно представлять доступ к свойству: 't => t.MyProperty'.

Итак, как это можно сделать? Я хотел бы избежать ненужных запросов, таких как выборка объекта вручную следующим образом:

user.ParentChilds.ForEach(pc => pc.Child = db.Childs.FirstOrDefault(x => x.Id == pc.ChildId));



Ответы (1)


Похоже, я неправильно понимаю использование ThenInclude, поскольку оно относится к подсущности. Имея список, можно определить объект для загрузки также в таких списках:

var parentWithChilds = db.Parents.Include(p => p.ParentChilds)
    .ThenInclude(p => p.Child)
    .FirstOrDefault(p => p.Id == 1);

В Visual Studio есть проблемы с отображением этих перегрузок в intellisense, но они есть и не приводят к ошибкам.

person Lion    schedule 30.10.2016
comment
.ThenInclude имеет две перегрузки (при использовании свойства навигации коллекции). Один для TPreviousProperty, другой для ICollection<TPreviousProperty>. Некоторым кажется, что Visual Studio всегда показывает intellisense для варианта TPreviousProperty и показывает только методы расширения коллекции, а не модель. Но при вводе имени свойства без автозаполнения он выберет правильное (как вы сделали с .ThenInclude(p => p.Child) и не покажет ошибку компилятора. - person Tseng; 30.10.2016
comment
Да, в этом была проблема, сначала я не заметил перегрузку, потому что она отсутствовала в intellisense. - person Lion; 30.10.2016