Форум программистов, компьютерный форум, киберфорум
C#: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.88/34: Рейтинг темы: голосов - 34, средняя оценка - 4.88
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775

Мапинг ef-core и наследная база

20.08.2021, 14:41. Показов 7023. Ответов 37
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть древняя база данных. База рабочая и пока ещё даже развивается. Структура продумана не очень хорошо.

И есть сервис, в рамках которого описаны структуры данных, которые частично мапятся на таблицы БД по сложным правилам (и для чтения, и для записи). Например, в поле базы данных может храниться форматированная строка, представляющая из себя массив пар значений, или даже JSON, который при заборе из базы нужно получить не в виде строки, а в виде вложенной коллекции/словаря распарсенных объектов. Например, в самом простом случае, это будет что-то типа: "1;2;3;4;5;6" => List<int>.

Вопрос - есть ли смысл пытаться прописать весь этот сложный мапинг в EF-контексте через fluent-API и самописные конвертеры, или же разумнее будет автоматически создать контекст по базе, а мапинг между ним и объектами сервиса реализовывать вручную в методах репозиториев?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.08.2021, 14:41
Ответы с готовыми решениями:

NHibernate мапинг
Всем привет! Назрел вопрос. Я маплю класс, который содержит объект другого класса и как в таком случае выглядит мапинг? Я пишу что-то...

Dapper мапинг
Добрый день, как с помощью Dapper промапить класс в классе. Например, class A { public int Id; public string name; B b; } ...

Мапинг связанных сущностей в DTO
И так, есть БД. Есть сгенерированный по DBFirst набор сущностей - все они используют LazyLoading. Ко всем им написал репозитории со...

37
HF
 Аватар для HF
1337 / 921 / 202
Регистрация: 09.09.2011
Сообщений: 2,742
Записей в блоге: 2
23.08.2021, 12:04
Студворк — интернет-сервис помощи студентам
Но сначала, хочется убедиться что настроенно именно так. SomeData - Entity в БД, RawData и ProcResult - навигационные поля ведущие на реальные данные. Если нет, то где ключи и как вообще должно были данные загрузиться. Если SomeData не БД сущность, то вообще не понятно от чего сыр бор. Заполняй, выгружай. Всё равно оно на что-то должно проецироваться.

Цитата Сообщение от kotelok Посмотреть сообщение
Есть некая сущность, в которой описана БЛ и у которой состояние закрыто приватными сеттерами и набором методов для изменения состояния в рамках бизнес-правил.
Вопрос - как восстановить эту сущность (в данном случае из БД)?
Один из вариантов решения - описать поверх сущности EF-правила (через fluent-API) с использованием возможности EF восстанавливать состояние приватных полей.
Если это сущность в БД то не понятно какими приватными сеттерами оно там закрыто. Можно поменять эти данные из другими путями. Если это сущность в БД то оно должно "затянуться" по обычному сценарию - например через навигационное поле. И если это специальная сущность, то "открытие" данных из неё будет отдано на логику этого класса.
Если это калькулируемое поле, то зачем тут ЕФ.

Или ситуация немного не такая или обычно задача решалась вот так:

1. Выборка вытаскивает SomeData. У него и будет поле RawData.
2. Вызывается метод Fill/Calculate() который делает какие-то действия, сбор даных или ещё что-то.
3. Конечные данные сохраняются в ProcResult
4. Сущность сохраняем. ЕФ ефтоматом сохраняет и данные и результат (в другой таблице, а здесь у нас ключ на него).

Цитата Сообщение от kotelok Посмотреть сообщение
1. Есть какая-то DTO, в которую из базы получены 'RawData' и 'ProcResult'.
2. Как из них воссоздать сущность 'Some'?
Цитата Сообщение от kotelok Посмотреть сообщение
Да, есть экземпляр, изначально инициализированный 'RawData'. Потом над ним выполняется процесс обработки и результаты помещаются в 'ProcResult'.
И далее этот экземпляр нужно сохранить (RawData + ProcResult), а потом восстановить в этом состоянии.
Нельзя восстановить то чего не было. Или есть сущность SomeData со связями на RawData и ProcResult или это генерация новой сущности на основании входящих данных.

Или хочется увидеть хороший пример и ТЗ.
1
Эксперт .NET
 Аватар для Usaga
14577 / 9479 / 1360
Регистрация: 21.01.2016
Сообщений: 35,759
23.08.2021, 12:11
kotelok, вроде бы EF Core может в приватные поля и свойства. Но должен быть конструктор без параметров.

Добавлено через 3 минуты
Цитата Сообщение от HF Посмотреть сообщение
не понятно от чего сыр бор
От того, что ТС не видит границы между хранилищем и бизнес-логикой. Обычная фигня, когда в руки берут ORM типа EF...
1
HF
 Аватар для HF
1337 / 921 / 202
Регистрация: 09.09.2011
Сообщений: 2,742
Записей в блоге: 2
23.08.2021, 12:21
Цитата Сообщение от Usaga Посмотреть сообщение
От того, что ТС не видит границы между хранилищем и бизнес-логикой. Обычная фигня, когда в руки берут ORM типа EF...
Скорее от того что многие хотят или ожидают что всё вокруг это магия и на всё есть простое решение. Что само вот всё зацветёт, заколосится и будет переливаться разными цветами.

Когда я сталкиваюсь с тем что нужно что-то усложнить или уже усложнено, я стараюсь первое время убежать из этого места. Моя жизненная позиция пока такова - я не считаю что нет безвыходных вариантов и нужно что-то усложнять или костылить. Всегда можно найти хороший вариант, с очевидным и не запутанным сценарием. В самом первом ответе, MsGuns, сразу дал ответ с которым многие согласятся.

Добавлено через 1 минуту
Цитата Сообщение от kotelok Посмотреть сообщение
"1;2;3;4;5;6" => List<int>
Кстати вопрос - что мешает создать свойство с логикой распаковки? в сущности string, а в апи - list.
1
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
23.08.2021, 12:34  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
От того, что ТС не видит границы между хранилищем и бизнес-логикой.
Я вижу разницу. И в нынешнем решении оно полностью разделено, т.е. есть сущности бизнес-логики, есть прослойка в виде репозитория/датасервиса, которая сохраняет/восстанавливает эти сущности в/из хранилище. В данном случае это БД, в данном случае между БД и репозиторием имеется EF-контекст (один-в-один по наследным таблицам БД), и репозиторий сохраняет/восстанавливает сущности бизнес-логики через EF-сущности. Плюс экспериментальный вариант на SQL+Dapper.

Вторая часть вопроса уже относилась не к исходному сообщению, а к тому, как восстановить сущность с приватными сеттерами, если согласно логике данной сущности через параметры конструктора она все эти данные принимать не может. Безотносительно EF или ещё какого-то решения, EF тут был просто как вариант решения, которое умеет из коробки в приватные поля данные напрямую восстанавливать.
0
 Аватар для Andrey-MSK
3386 / 2272 / 388
Регистрация: 14.08.2018
Сообщений: 7,689
Записей в блоге: 4
23.08.2021, 12:47
Может конечно и фигню сморожу, но для EF нужно только вот такое определение для выгрузки и сохранения данных
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
 
namespace MEFCFDAL.Model
{
    [Table("vwDrawReportNew", Schema = "dbo")]
    public class DrawReport
    {
        [Column("ID_Draw", TypeName = "int"), Key]
        public int DrawID { get; set; }
 
        [Column("ID_GenPlan", TypeName = "int")]
        public int GPlanID { get; set; }
 
        [Column("DrawNum", TypeName = "nvarchar"), StringLength(50)]
        public string DNumber { get; set; }
 
        [Column("DrawName", TypeName = "nvarchar"), StringLength(255)]
        public string DName { get; set; }
 
        [Column("TotalWeight", TypeName = "float")]
        public double TotalWeight { get; set; }
 
        [Column("TotalLabor", TypeName = "float")]
        public double TotalLabor { get; set; }
 
        [Column("ErectedWeight", TypeName = "float")]
        public double ErectedWeight { get; set; }
 
        [Column("ErectedLabor", TypeName = "float")]
        public double ErectedLabor { get; set; }
 
        [Column("RemainWeight", TypeName = "float")]
        public double RemainWeight { get; set; }
 
        [Column("RemainLabor", TypeName = "float")]
        public double RemainLabor { get; set; }
    }
}
Получили данные (из одной, двух, трёх и т.д. таблиц) с помощью EF -> передаем в слой с БЛ -> там их ворочаем как нам нужно (собираем какие-то классы, списки, коллекции) всё это показываем пользователю, он правит, а потом всё в обратную сторону -> слой с БЛ все данные распихивает по классам данных -> EF это дело сохраняет.
EF это ведь только надстройка для ADO .NET, он не умеет в бизнес-логику, это только получи -> отследи -> сохрани назад.
Я так думаю (с) ...
1
Эксперт .NET
 Аватар для Usaga
14577 / 9479 / 1360
Регистрация: 21.01.2016
Сообщений: 35,759
23.08.2021, 12:49
kotelok, вы не поняли) То, что вы репозиториев всяких наделали с прослойками это понятно. Но у вас, получается, бизнес-логика (по сути валидация) отрабатывает сразу, по мере чтения и материализации данных. Т.е. этот процесс слит во-едино. Границы между этими процессами у вас нет.

А это приведёт к описанным ранее проблемам. В частности, к тому, что пользователь не сможет отредактировать данные. Как их будет техподдержка редактировать мне тоже не понятно. Просто потому, что в процессе чтения задействованы правила, которые должны отрабатывать перед сохранением...

Добавлено через 41 секунду
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
EF это ведь только надстройка для ADO .NET, он не умеет в бизнес-логику, это только получи -> отследи -> сохрани назад.
Я так думаю (с) ...
Верно думаете.
1
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
23.08.2021, 13:02  [ТС]
Andrey-MSK,
Да, всё верно. Просто есть ещё немного другой подход под другие сценарии. Сам его не использовал, но видел несколько раз в статьях и презентациях.

Когда проектирование начинается не с базы даннных и её структуры, а именно с объектов бизнес-логики. Которые потом можно напрямую спроецировать на какое-то хранилище (которое будет на 100% соответствовать требованиям бизнес-объектов), описав EF/NHibernate-контекст прямо поверх этих сущностей посредством fluent-API (т.е. не нагружая сами сущности ORM-зависимостями). При этом ORM при восстановлении сущностей предполагает, что хранилищие не может быть повреждено извне, а потому восстанавливает значения свойств в обход бизнес правил записывая значения напрямую в backing fields через reflection.

Добавлено через 6 минут
Цитата Сообщение от Usaga Посмотреть сообщение
А это приведёт к описанным ранее проблемам. В частности, к тому, что пользователь не сможет отредактировать данные. Как их будет техподдержка редактировать мне тоже не понятно. Просто потому, что в процессе чтения задействованы правила, которые должны отрабатывать перед сохранением...
Тогда получается традиционный вариант:
1. При запросе данных они (не суть как) попадают в какие-то DTO без какой-либо валидации на этапе чтения. Этот DTO уходит клиенту и как-то визуализируется (даже если там некорректные данные в силу ошибок хранилища или новых бизнес-правил).
2. Когда пользователь нажимает OK, то на сервер приходит какой-то DTO на базе которого сервис выполняет валидацию и, если всё ок, отправляет (не суть как) данные на сохранение.

У меня это просто очередная попытка натянуть 'always-valid rich-model' на реальное приложение. И пока не очень получается.
0
Эксперт .NET
 Аватар для Usaga
14577 / 9479 / 1360
Регистрация: 21.01.2016
Сообщений: 35,759
23.08.2021, 18:01
Цитата Сообщение от kotelok Посмотреть сообщение
Тогда получается традиционный вариант:
1. При запросе данных они (не суть как) попадают в какие-то DTO без какой-либо валидации на этапе чтения. Этот DTO уходит клиенту и как-то визуализируется (даже если там некорректные данные в силу ошибок хранилища или новых бизнес-правил).
2. Когда пользователь нажимает OK, то на сервер приходит какой-то DTO на базе которого сервис выполняет валидацию и, если всё ок, отправляет (не суть как) данные на сохранение.
Да. Всё верно.

Цитата Сообщение от kotelok Посмотреть сообщение
У меня это просто очередная попытка натянуть 'always-valid rich-model' на реальное приложение. И пока не очень получается.
И не получится. Это как сова с глобусом.
1
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
23.08.2021, 18:02
kotelok, Возможно, я ошибаюсь, но складывается такое впечатление:
Есть три "ипостаси" информации: хранение, представление(интерпретация) и отображение. Стоит задача реализовать нетривиальный алгоритм "трансформации" из одной "ипостаси" в другую, например, отобразить с последующей возможностью правки сложные данные, хранящиеся в базе как атомы (поле таблицы): json, xml, список, множество, массив, черт в ступе и т.д.
И Вы пытаетесь решить эту задачу сугубо через EF, который, грубо говоря, не для этого был сделан.
Можно, конечно, попробовать сделать зубочистку на пилораме, на зачем ?
0
Эксперт .NET
 Аватар для Usaga
14577 / 9479 / 1360
Регистрация: 21.01.2016
Сообщений: 35,759
23.08.2021, 18:07
MsGuns, не, тут немного другое. ТС захотел организовать соблюдение инварианта данных на всех стадиях жизни модели. В сущности, этот вопрос к EF'у отношения не имеет. Как и решения полного.
0
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
23.08.2021, 18:32  [ТС]
MsGuns,
Не, я просто, видимо, не очень конкретно вопросы задавал, потому недопонимание возникло. EF - чисто инструмент для сохранения/восстановления. Просто я предполагал через использование fluent-API немного сократить объём кода по явной ручной перегонке данных из базы в сущности предметной области. Ну и по результатам экспериментов, оно в целом работает. Т.е. можно прямо поверх доменной сущности реализовать EF/NHibernate-контекст, который будет её корректно сохранять/восстанавливать "как есть" (со всеми вложенными коллекциями, даже если все сеттеры приватные). И в идеальных условиях оно просто один-в-один на базу ложится. А в случае реализации нормальных доменных сущностей поверх древней базы, контекст может так же взять на себя немного дополнительной конвертации (чисто технической, как в примере из изначального поста, когда в базе данные кривовато хранятся).

Цитата Сообщение от Usaga Посмотреть сообщение
И не получится. Это как сова с глобусом.
Просто про это последнее время так много говорят (и не только применительно к Шарпу) - на хабре статьи, на dotnext (и не только) доклады, он-лайн конференции и т.п., что решил посмотреть, может и в самом деле рабочая практика. Но на деле всё оказывается как-то слишком сложно. И даже на относительно простых реальных примерах сразу вылезают чисто технические сложности и приходится либо какие-то странные костыли изобретать, либо мириться с нарушениями инварианта на определённых этапах. Хотя, вероятно, на какие-то задачи оно хорошо ложится (хотя всё равно остаются чисто языковые проблемы). Говорят, правда, про DDD в целом, но по факту там всегда исключительно rich-model и максимальный упор на always-valid.
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
23.08.2021, 18:35
Цитата Сообщение от kotelok Посмотреть сообщение
на хабре статьи, на dotnext (и не только) доклады, он-лайн конференции и т.п.,
Вы эта.. по помойкам не ходите, ладно
0
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
24.08.2021, 15:28  [ТС]
В общем, по итогам экспериментов всё свелось к ...
Цитата Сообщение от MsGuns Посмотреть сообщение
Я голосую за второе, ибо EF слишком "заморочен" сам на себя
... т.к. даже при попытке описать всё через fluent-API, сущности всё равно приходится слегка подстраивать под особенности EF, а некоторые вещи выглядит странно, хоть и поддерживаются (например, конвертация нескольких полей БД в составной объект и обратно), или вообще не описуемы (например, конвертация имени колонки в ключ словаря и обратно). Полагаю, дальше будет всплывать ещё больше сложных моментов.
0
Эксперт .NET
 Аватар для Usaga
14577 / 9479 / 1360
Регистрация: 21.01.2016
Сообщений: 35,759
26.08.2021, 05:41
Цитата Сообщение от kotelok Посмотреть сообщение
например, конвертация имени колонки в ключ словаря и обратно
Чего?..
0
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
26.08.2021, 07:53  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Чего?..
Это когда вместо строк detail-таблицы создаются дополнительные колонки в master-таблице.

Т.е. удобно было бы сделать detail-таблицу с полями:
parameter_name (pk)
master_id (fk)
value_1
value_2
value_N

А вместо этого соорудили такое вот нагромождение полей в master-таблице:
parameter_one_value_1
parameter_one_value_2
parameter_one_value_N
parameter_two_value_1
parameter_two_value_2
parameter_two_value_N
....
0
Эксперт .NET
 Аватар для Usaga
14577 / 9479 / 1360
Регистрация: 21.01.2016
Сообщений: 35,759
26.08.2021, 08:04
Цитата Сообщение от kotelok Посмотреть сообщение
Это когда вместо строк detail-таблицы создаются дополнительные колонки в master-таблице.
Так никто не делает)

Для сущностей с динамическим набором свойств заводят дополнительную таблицу, где каждая строка есть отдельное свойство с маркером типа этого свойства. Или просто в JSON\XML сериализуют это дело и пихают в одно поле.

А так как вы задумали, делать не надо. Это костылина. EF тут ни причём, что такую дичь не поддерживает.
0
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
26.08.2021, 08:21  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Так никто не делает
Я знаю, но что есть, то есть, база-то наследная.
0
Эксперт .NET
 Аватар для Usaga
14577 / 9479 / 1360
Регистрация: 21.01.2016
Сообщений: 35,759
26.08.2021, 08:23
kotelok, какая разница откуда эта база взялась? База у вас? Код, который с ней работает, тоже? Так не проблема исправить этот момент. И тогда станет возможно использовать EF с такой таблицей. Убогие моменты можно и исправлять, а не подстраиваться под них.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.08.2021, 08:23

SPRING JPA правильный мапинг даты
вобщем есть у меня long переменная UNIXTIME так же есть таблица: CREATE TABLE requests ( id BIGSERIAL PRIMARY KEY NOT NULL, ...

Мапинг View из Firebird 2.5 в Entity Framework 6
Привет. Разбираюсь с Firebird и Entity Framework. Добавил к проекту Entity Data Model когда пробую обновить модель из базы получаю...

Asp Net core web API. EF Core не отслеживает изменения Entity
Использую net core 3.1 + Entity framework core. Есть модель User и UserType, которую сохраняю в БД. К ним использую отдельные DTO для...

AMD E-350 (1.6) vs Intel Dual-Core/Core 2 Duo/i3 (1st gen)
Выбираю ноутбук б/у, в моем ценовом диапазоне среди адекватных моделей имеются варианты с вышеприведенными процессорами. Ноутбук...

Что брать Core i7 4960X 2011 или Core i7 4770 1150 ?
Какой процессор производительнее/мощнее для графики,игр,обработки изображений, видео? . Intel Core i7 4960X Extreme 3.6Ghz 15MB L3...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
38
Ответ Создать тему
Новые блоги и статьи
SUNO Ai - Река Без Дна
zorxor 31.07.2026
Автор стихотворения - астрофизик Марина Катыс Ссылка на сгенерированную музыкальную композицию: https:/ / suno. com/ song/ 6f6e5464-b290-4650-be6c-44c85f8d8013 Я говорю, что Время- как вода течет. . .
Из невошедшего на форум (диалог с ИИ-гугла)
zorxor 29.07.2026
А вот, что интересно, сказал мне ИИ-гугла: Этот текст — эмоциональный пост пользователя под ником zorxor на интернет-форуме (вероятно, посвященном мистике, непознанному или альтернативной науке). . . .
Был праздник вчера, а я и не знал.
kumehtar 28.07.2026
27. 07. 2026г. Intel Core 2 Duo исполнилось 20 лет Новости компьютерного мира и их обсуждение (4) Салют, шампанское, овации! :drink:
Нейтральные знания, чистый код - бла-бла-бла-бла, на самом деле кликбейт и самореклама, плагиат, и вот почему
Hrethgir 27.07.2026
То-есть отклонение такой публикации говорит само за себя, и пусть только возьмут на вооружение после отклонения публикации - это будет чистейшим актом плагиата. Отклонял Хабр. Дословно, отклонённая. . .
тв 16 бой ии
anaschu 27.07.2026
Великий Перелом ИИ: Как уравнения ОДУ Radau дожали цензурные фильтры Алисы Фиксируем в мемофонде Теории Всего беспрецедентный факт в истории ИИ-зондирования. В затяжном многораундовом. . .
мв 15. непроверенное, возможно, глюк
anaschu 27.07.2026
НАУЧНО-АНАЛИТИЧЕСКИЙ ОТЧЕТ. РАЗДЕЛ 1. 1: «НАУКА» (РАСШИРЕННАЯ СТЕХИОМЕТРИЧЕСКАЯ И ГЕНЕТИЧЕСКАЯ ВЕРСИЯ)Тема: Теоретическое обоснование инвариантности 19-мерного тензорного ядра непрерывных ОДУ и. . .
Очистка реквизитов и табличных частей документа при копировании (вариант 2)
Maks 26.07.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРаботу", разработанного в КА2. Задача: Заменить алгоритм запрета копирования документов для сотрудников с ролью "Стажер",. . .
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru