TLDR : Я хотел бы знать, возможно ли использование разных «включающих логик» для одного типа сущности в одном запросе в ядре EF.
Редактировать : Просто чтобы прояснить, в названии я сказал, что отслеживаю сущности, потому что я думаю, что это то, что делает EF, но .AsNoTracking()
здесь ничего не делает, прежде чем кто-либо предложит.
Проблема в относительно небольшом приложении React, поддерживаемом приложением ASP.NET Core web api. Что я хочу сделать, так это, когда я звоню api/parents
, я хочу, чтобы приложение дало мне json, который выглядит следующим образом:
[
{
"id": "parentid1",
"extraProperty": "value",
"children": [
{
"id": "childid1",
"parent": {
"id": "parentid1",
"extraProperty": "value"
}
}
]
}
]
Моя установка выглядит следующим образом:
запрос EF :
(from p in _context.Parents
select p)
.Include(p => p.Children)
.ThenInclude(c => c.Parent)
.ToList();
После этого у меня есть AutoMapper, отображающий сущность в dto, там происходит не так много. Я также использую по умолчанию Json Serializer (Newtonsoft) для приложения. Это настроено с SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore
.
При такой настройке вызов API возвращает этот ответ:
[
{
"id": "parentid1",
"extraProperty": "value",
"children": [
{
"id": "childid1"
}
]
}
]
Который, как вы видите, "игнорирует" собственную ссылку на родителя.
Решение, которое я придумал, состояло в том, что я должен настроить Newtonsoft для «сериализации» эталонных циклов, и я попробовал это. И он выбрасывает, потому что приведенный выше запрос EF возвращает список сущностей, который выглядит следующим образом:
[
{
"id": "parentid1",
"extraProperty": "value",
"children": [
{
"id": "childid1",
"parent": {
"id": "parentid1",
"extraProperty": "value",
"children": [
{
"id": "childid1",
"parent": {
"id": "parentid1",
"extraProperty": "value"
...
}
}
]
}
}
]
}
]
Если вы посмотрите на мои вызовы Include, там явно сказано, что для моих дочерних объектов мне нужен только родительский объект, а внутри этого родительского объекта никаких других ссылок нет.
На мой взгляд, EF использует начальную настройку .Include(child).ThenInclude(parent)
, когда сталкивается с любым родительским объектом для этого запроса. Поэтому, когда он находит Parent
объект в Child
объекте, вместо использования no include (которого у меня нет после ThenInclude
), он использует .Include(child).ThenInclude(parent)
.
Я не хочу решать эту проблему путем хаков с помощью картографа или сериализатора, если мне это не нужно. Хотелось бы узнать, возможно ли то, что я ищу: использовать разные «логики включения» для одного типа сущности в одном запросе.