EF Core односторонняя привязка сущностей - PullRequest
0 голосов
/ 25 сентября 2018

Я настроил самоссылающуюся сущность, используя EF Core, которая выглядит следующим образом:

Сущность

public class DetailType
{
    public int DetailTypeId { get; set; }
    public string Name { get; set; }

    public int? ParentTypeId { get; set; }
    public DetailType ParentType { get; set; }
    public IEnumerable<DetailType> ChildTypes { get; set; }
}

Связывание

modelBuilder.Entity<DetailType>()
    .ToTable("detailtype")
    .HasOne(x => x.ParentType)
    .WithMany(x => x.ChildTypes)
    .HasForeignKey(x => x.ParentTypeId);

Я получаю эти объекты через API, и текущий результат выглядит примерно так:

[
    {
        "detailTypeId": 20,
        "name": "Money",
        "parentTypeId": null,
        "parentType": null,
        "childTypes": null
    },
    {
        "detailTypeId": 22,
        "name": "Optional Extra",
        "parentTypeId": null,
        "parentType": null,
        "childTypes": [
            {
                "detailTypeId": 42,
                "name": "Extra Nights",
                "parentTypeId": 22,
                "childTypes": null
            }
        ]
    },
    {
        "detailTypeId": 42,
        "name": "Extra Nights",
        "parentTypeId": 22,
        "parentType": {
            "detailTypeId": 22,
            "name": "Optional Extra",
            "parentTypeId": null,
            "parentType": null,
            "childTypes": []
        },
        "childTypes": null
    }
]

Проблема, с которой я столкнулся, заключается в том, что третий элемент в массиве - это простообратная сторона второго.Есть ли способ избежать этого, чтобы у меня были только родительские отношения -> дочерние, а не оба родительские -> дочерние, а также дочерние -> родительские.Приведенный выше пример является сильно урезанной версией того, что на самом деле возвращает мой API, поэтому я хочу максимально уменьшить ненужный раздувание, потому что там будет происходить много отношений.

В идеале то, что яхочу просто избавиться от свойства ParentType, но при этом иметь коллекцию ChildTypes, но я не уверен, как определить это в построителе модели.

РЕДАКТИРОВАТЬ:

Я удалил свободные отношения, так как они не нужны.Я также попробовал следующее:

var roots = this.Items.Where(x => x.ParentTypeId == null);
foreach (var root in roots)
{
    root.ChildTypes = this.Items.Where(x => x.ParentTypeId == root.DetailTypeId);
}

return roots.ToList();

(кстати, this.Items - это DbSet)

Однако для этого необходимо изменить ChildTypes на IQueryable, и когда я это сделаючто я получаю следующее исключение:

Тип свойства навигации 'ChildTypes' для типа сущности 'DetailType' - это 'EntityQueryable', который не реализует ICollection.Свойства навигации по коллекции должны реализовывать ICollection <> целевого типа.

1 Ответ

0 голосов
/ 25 сентября 2018

Перво-наперво - вам не нужно указывать эти отношения в конструкторе моделей.Он вычисляет это сам.

Тогда по вашему вопросу - первое, что приходит мне в голову (я не знаю весь ваш набор данных), это получить все DetailType объекты, которые имеютParentTypeId == null.

Таким образом вы получите корни, а затем рекурсивно создадите tree дочерних элементов.

Выполнение этого очистит ваш результат, и вы увидите структуру такой, какой хотите ее видеть.

...