|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
EF Core, CodeFirst Нужно получить клон сущности с клонами связанных сущностей. Точнее почти со всеми. К примеру (сразу подчеркиваю, пример условный) клонируем заказ пользователя, нужно также получить клон всех номенклатурных позиций с ценами заказа (корзина, условно говоря), но при этом ссылки на номенклатурный справочник остаются, то есть записи номенклатурного справочника клонированию не подлежат. Дополнительно: - в процессе клонирования нужно изменить некоторые поля в некоторых сущностях (к примеру дату) - задача осложняется тем, что есть циклические ссылки, то есть если сделать втупую глубокое копирование, оно просто зациклится, нужно учитывать уже клонированные объекты. Описание, что нужно клонировать, какие ссылки сохранять, какие поля поменять, можно было бы описать с помощью атрибутов на свойствах сущностей или на самих сущностях. Кто-нибудь решал такую задачу, может есть какие-то готовые инструменты? Думал, может автомаппер приспособить, но с учетом требований мне кажется, это будет выглядеть громоздко, проще свой инструмент написать. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 15:04 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
Можно попробовать создать второй экземпляр контекста и приаттачить к нему граф обьектов загруженных в первом контексте как новые обьекты. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 16:13 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
fkthat, Можно и не аттачить. Простой второй контекст). А ещё лучше денормализация через проекцию. Спроецировать новые типы без справочников на млн.позиций. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 17:21 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
fkthatМожно попробовать создать второй экземпляр контекста и приаттачить к нему граф обьектов загруженных в первом контексте как новые обьекты.Интересная мысль. По идее, достаточно просто загрузить корневую сущность со всеми необходимыми инклюдами, потом пройтись по всем объектам контекста, стирая им Id и отключая от контекста, а потом добавить корневую сущность как новую, можно прямо в тот же контекст. Или можно просто загрузить AsNoTracking и передобавить в контекст. Правда стирать ID-шники придется после добавления в контекст, потому как нужно как-то получить список сущностей. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 17:32 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
Shocker.Pro, dbContext.Entry(entity).State = EntityState.Detached; Зачем этот гимор, дело ваше. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 17:40 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
Shocker.ProКто-нибудь решал такую задачу, может есть какие-то готовые инструменты? Самый в доску тупой, но достаточно хорошо сопровождаемый и надёжный, это маппинг (например, AutoMapper) Entity → DTO DTO → Entity Но коли клонирование это стабильная операция, то можно её сделать операцией клонирования, с прописанной в ней логикой. Где размещаешь свою логику? Сервисы? Команды? Воркеры? Вот там и опиши. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 18:16 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
fkthatМожно попробовать создать второй экземпляр контекста и приаттачить к нему граф обьектов загруженных в первом контексте как новые обьекты. Это самый плохой сценарий, который учитывает подробности реализации репозитория. Сопровождаться будет плохо, и пахет уже на взлёте отвратительно. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 18:17 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
hVosttНо коли клонирование это стабильная операция, то можно её сделать операцией клонирования, с прописанной в ней логикой. Где размещаешь свою логику? Сервисы? Команды? Воркеры? Вот там и опиши.Я так и сделал для одного из графов, но задолбался и решил поискать способ попроще. И опять же - из-за циклических ссылок тупой маппинг не подходит, пришлось делать еще и кеш клонированных сущностей, чтобы не дублировать их. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 18:20 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
hVosttСамый в доску тупой, но достаточно хорошо сопровождаемый и надёжный, это маппинг (например, AutoMapper) Entity → DTO DTO → EntityА тут придется объяснять мапперу, что требуется клонировать, что не требуется. В случае автомаппера это будут коллбэки и наглядность будет совсем не на высоте. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 18:25 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
Shocker.Pro, AutoMapper? ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 18:32 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
Shocker.ProА тут придется объяснять мапперу, что требуется клонировать, что не требуется. В случае автомаппера это будут коллбэки и наглядность будет совсем не на высоте. Почему, конфигурация маппинга. Конструктор, принимающий экземпляр своего типа для сущности, не рассматривал? ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 18:33 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
hVosttAutoMapper?да hVosttПочему, конфигурация маппинга.придется пилить конфигурацию под каждый конкретный граф, а этого не хочется. Если же делать через атрибуты свойств сущности, то придется приделать к мапперу еще и логику hVosttКонструктор, принимающий экземпляр своего типа для сущности, не рассматривал?ну почти. Я просто сделал метод Clone() у сущности. Но в обоих случаях проблема опять же в циклических ссылках, их нужно учитывать, что в маппере, что в клонировании. Иначе бесконечный цикл и StackOverflow. А вот EF умеет это автоматом, вот что привлекательно. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 18:43 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
hVosttShocker.Pro, AutoMapper? Автомеппер, афайк, не разрулит циклические ссылки. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 18:43 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
fkthathVosttShocker.Pro, AutoMapper? Автомеппер, афайк, не разрулит циклические ссылки.пример приведи циклической. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 18:49 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
Shocker.Proвот EF умеет это автоматом,в маппинге есть направления связей. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 18:51 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
fkthatАвтомеппер, афайк, не разрулит циклические ссылки. jbogardAutoMapper works OK if the destination objects overload .Equals, have you tried that? https://github.com/AutoMapper/AutoMapper/issues/314 ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 19:05 |
|
Клонирование графа сущностей в EF
|
|||
---|---|---|---|
#18+
ответ 2013 года. А вот посвежее Circular references Previously, AutoMapper could handle circular references by keeping track of what was mapped, and on every mapping, check a local hashtable of source/destination objects to see if the item was already mapped. It turns out this tracking is very expensive, and you need to opt-in using PreserveReferences for circular maps to work. Alternatively, you can configure MaxDepth: // Self-referential mapping cfg.CreateMap<Category, CategoryDto>().MaxDepth(3); // Circular references between users and groups cfg.CreateMap<User, UserDto>().PreserveReferences(); Starting from 6.1.0 PreserveReferences is set automatically at config time whenever the recursion can be detected statically. If that doesn't happen in your case, open an issue with a full repro and we'll look into it. http://docs.automapper.org/en/v6.2.2/5.0-Upgrade-Guide.html?#circular-references ... |
|||
:
Нравится:
Не нравится:
|
|||
07.06.2018, 19:19 |
|
|
start [/forum/moderation_log.php?user_name=bix]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
get settings: |
11ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
157ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
49ms |
get tp. blocked users: |
2ms |
others: | 440ms |
total: | 716ms |
0 / 0 |