Страницы

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

среда, 6 марта 2019 г.

Добавление в базу нового объекта с ссылкой на уже существующие объекты Entity Framework

У меня есть таблица с задачами и таблица с тегами между ними связь многие ко многим.
public class DbTask { [Key] public int TaskId { get; set; } public string Name { get; set; }
public virtual ICollection Tags { get; set; } }
public class DbTag { [Key] public int TagId { get; set; } public String Name { get; set; }
public virtual ICollection Tasks{get; set;} }
Я создаю объект класса DbTask на клиенте и добавляю список уже существующих в базе данных объектов DbTag. После этого отправляю созданный объект на сервер, где добавляю его в базу данных. При добавлении через метод Add в таблицу заносится не только запись о новом DbTask, но и новые DbTag. Как мне сделать что бы новая запись связывалась с уже существующими DbTag?


Ответ

Есть несколько вариантов решения этой задачи:
Создаёте DbTask, делаете селект нужных тегов потом в коллекцию Tags добавляете существующие DbTag. (более правильный, без селекта) Создаёте DbTask, в него добавляете созданные DbTag и в контексте помечаете каждую сущность DbTag как не изменённую,
context.Entry(DbTag).State = EntityState.Unchanged
что позволяет entity framework создать нужные связи.
Ссылка на документацию про присоединение к контексту отсоединённых сущностей
Вообще хорошей практикой в DDD является приведение связи многие ко многим к однонаправленной один ко многим. Как в вашем случае это можно сделать и для чего? Например у каждой задачи может быть несколько тегов и когда вы запросите задачу с её тегами то коллекция тегов будет достаточно короткой, а вот у тега может быть огромное количество задач и запросить тег с его задачами в одном запросе может оказаться затратной операцией и для её решения нужно будет запрашивать задачи используя лимит. А лимитировать сущности в Include() в entity framework нет возможности. Из этого следует, что декларация коллекции Tasks в DbTag заведомо может привести к серьёзным последствиям и такие действия лучше ограничить (не декларировать возможность такого запроса в коде, то есть убрать из кода DbTag коллекцию Tasks). Запросить все таски помеченные тегом можно будет через коллекцию тасков.

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

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