26 / 11 / 1
Регистрация: 20.05.2015
Сообщений: 211
|
|||||||||||
1 | |||||||||||
Рефлексия обобщенных коллекций для вызова методов при неизвестном типе08.06.2022, 18:01. Показов 889. Ответов 23
Если вкратце: Использую Entity Framework в котором используется множество коллекций сущностей DbSet;
Все коллекции разные, но почти все имеют общую суть (обрабатываются одинаково). Вопрос, как мне через рефлексию сделать возможным работу со всеми коллекциями одним кодом (типа Load, преобразование в таблицу, Save и прочие непотребства). Можно, конечно, каждый раз все таблицы перечислять, но как-то это не по програмерски. Абстрактный нерабочий пример (так как в метод расширение Load надо передать обобщение с аргументом):
0
|
08.06.2022, 18:01 | |
Ответы с готовыми решениями:
23
Рефлексия обобщенных типов Алгоритм для вызова методов с массива Специальные методы для вызова необъявленных методов объекта Рефлексия методов и конструкторов |
3683 / 2594 / 719
Регистрация: 02.08.2011
Сообщений: 6,964
|
|
08.06.2022, 19:20 | 2 |
Generic-и на основе DbSet<T> вам в помощь и никакая рефлексия не нужна.
Добавлено через 47 минут Если маппинг нужен, то AutoMapper, насколько я помню, может вроде даже Expression-ы маппить при выполнении запросов.
1
|
26 / 11 / 1
Регистрация: 20.05.2015
Сообщений: 211
|
||||||
19.11.2022, 17:16 [ТС] | 3 | |||||
Вернулся к вопросу через пол года ...
Как я понимаю, что джейнерик, что AutoMapper всё равно требуют знать тип класса уже на момент компиляции. Пробовал разные варианты через рефлексию, но что-то прям адские конструкции извлечения классов и методов и по факту всё равно не работает . Вопрос то в целом такой, в программе есть 20 абсолютно разных по содержанию таблиц DataTable и 20 сущностей в DbSet, можно ли передать данные из DataTable в DbSet одной общей процедурой, или только через 20 сопоставлений, пусть и в виде вызова обобщений? В целом за то время, которое я на это потратил я бы уже тмного тысяч раз написал бы эти сопоставления, но просто как-от не по программерски это... Добавлено через 42 минуты Пока мой ограниченный интеллект создал только такое, наиболее компактное решение практически без будбилрования кода:
0
|
1150 / 858 / 263
Регистрация: 30.04.2009
Сообщений: 3,598
|
|
19.11.2022, 21:50 | 4 |
Написать то можно только похвалу от старших коллег за такое непотребство врядли получите, разве что они находятся на таком же уровне осознания.
Код должен быть в первую очередь поддерживаемым и отлаживаемым. Во первых, алгоритмы использующие рефлексию нечитаемы как бы автор ни был убежден в обратном. Во вторых, использование рефлексии обрывая связи между объектами нарушает статический анализ что невероятно усложняет исследование чужого кода.
0
|
26 / 11 / 1
Регистрация: 20.05.2015
Сообщений: 211
|
|
19.11.2022, 22:53 [ТС] | 5 |
Спорить не буду, но в противном случае иногда может возникнуть многократное повторение почти идентичного кода. Что хуже? (если не рассматривать вариант, полной переделки архитектуры).
Так же иногда то, что без использования рефлексии потребует сотен строчек кода с использованием рефлексии может решиться в 3-5. Ну и опять же, разве WPF весь не про рефлексию? Все эти привязки по именам свойств и т.п.? С моей точки зрения обобщения, зачастую, гораздо сложнее читать, чем рефлексию. В целом удивлен такой точке зрения. Я то сам себе старший и младший товарищ, проблемы чтения рефлексии, это проблемы завтрашнего меня .
0
|
Модератор
|
|
19.11.2022, 23:44 | 6 |
werymag, совсем не понял вашу затею.
С точки зрения архитектуры приложения (а раз у нас ООП, то это самый верхний уровень абстракции), каждый DbSet<T> это отдельный Репозиторий.То что в данной реализации у вас все DbSet<T> отражают данные одной БД (в общем случае одного Хранилища) - это частный случай.Исходя из такого понимания архитектуры, я как то не могу представить, а для чего нужен метод UpdateTable ?И что содержится в WellDataTable table ? Почему её надо передавать во все таблицы (то есть DbSet)?
0
|
1150 / 858 / 263
Регистрация: 30.04.2009
Сообщений: 3,598
|
|
20.11.2022, 00:07 | 7 |
werymag, много чего сложно читать, если оно плохо запроектировано
Но у рефлексии два вышеупомянутых негативных свойства существуют по определению что делает этот инструмент более дорогим в долгосрочной перспективе, чем простыня кода. Относительно WPF я бы поспорил Там рефлексия совместно с кодогенерацией и спец инструменты для поддержки статического анализа связей между View и Model. Я для себя после многих лет выработал такое правило: если рефлексия разрывает связь между компонентами приложения - использовать её не стоит, если как крайний слой при интеграции со сторонними системами, то может быть разумным решением, но опять же зависит от сложности рефлексионного алгоритма. Хорошие примеры использования, по моему скромному мнению: - ORM фреймворки - Сериализаторы - Логгеры - использование атрибутов. Плохие примеры: - автомапперы - прочие самодельные инструменты для взаимодействия между двумя компонентами внутри одного приложения.
1
|
26 / 11 / 1
Регистрация: 20.05.2015
Сообщений: 211
|
||||||||||||||||
20.11.2022, 00:13 [ТС] | 8 | |||||||||||||||
Если правильно понимаю, то нет - БД одна, но таблицы абсолютно разные (по содержанию и смыслу).
В начале метода UpdateEntity<T> находится условие
То есть на вход метода (не обращайте внимание на WellDataTable, в данном случае это просто DataTable)
Если подытожить. У меня есть 20 таблиц DataTable с данными с которыми я работаю и есть 20 сущностей DbSet<T> полностью им соответствующих. Далее я хочу однозначно считывать данные с сущностей в любую таблицу DataTable, и так же затем обновлять базу данных при необходимости - заполнив DbSet<T> на основании изменённой DataTable. Можно сделать 20 методов, которые будут будут это делать, без использования джейнериков и рефлексии, но я яро ненавижу дублирование кода, так как постоянно забываю править все места, в случае правок. Прошу не критиковать саму идею использования DataTable, она вышла из работы OLEDB для Access DB, и сейчас всё огромное приложение работает на DataTable. Добавлено через 5 минут Буду иметь в виду и применять более осторожно. Хотя мне всегда нравилась красота методов на рефлексии, когда ты какой-то очень сложный набор действий делаешь буквально за несколько строк кода. Очень напоминает Питон, где вообще нет таких ограничений и можно сделать что-то очень сложное очень коротким и, в целом, простым алгоритмом.
0
|
1150 / 858 / 263
Регистрация: 30.04.2009
Сообщений: 3,598
|
|
20.11.2022, 00:15 | 9 |
werymag, если используется DataTable, то возникает вопрос зачем использовать EntityFramework, вместо ADO.NET.
Как первый этап миграции на типизированные модели данных?
0
|
Модератор
|
|
20.11.2022, 00:23 | 10 |
Воще, треш какой-то
Вы используете EF. Откуда у вас появились DataTable? Это же не "чистый" ADO. У вас должны быть коллекции с разными сущностями для каждого DbSet. У DbContext есть методы для работы с сущностями без обращения к DbSet: Entry(...), Set(...) и др. По тонкостям вам не подскажу - слабо знаю EF. Но исходники, в которых обрабатываются данные без свойств DbSet<T> несколько раз попадались. Насколько понимаю, свойства DbSet<T> - это просто удобная оболочка для методов DbContext. Буду. И что? Или парсите DataTable в нормальные коллекции, или не используйте EF. Если используете EF, то переводите приложение потихоньку на нормальные коллекции.
1
|
26 / 11 / 1
Регистрация: 20.05.2015
Сообщений: 211
|
|
20.11.2022, 00:25 [ТС] | 11 |
Наверное ADO.NET тут действительно лучше подходит. Как говориться "ктож знал то" . Так же мне показалось, что EntityFramework проще и приятнее чисто с точки зрения программирования, в дальнейшем я планировал повсеместно использовать уже его, потому дабы не разводить огород и кучи технологий решил его использовать и тут. Вообще изначально думал, что я прям в пару простых процедур смогу гонять данные из таблиц в типизированные структуры и обратно, а оказалось несколько сложнее (хотя, скорее, не сложно, а некрасиво).
0
|
Модератор
|
||||||
20.11.2022, 00:34 | 12 | |||||
Скорее всего тяга к процедурному программированию.
Задача (одна из) Шарпа это уменьшить вероятность различных, ошибок, багов. Строгая типизация позволяет многие ошибки выявлять при компиляции. И создавать гораздо боле оптимальный код. Рефлексия ломает это всё. Добавлено через 50 секунд Да. Так и есть Добавлено через 6 минут Можно. Но нужен более комплексный подход. Таблицы у вас это данные уровня потребителей Модели. Сущности EF - это уровень общения Модели с Репозиторием. Нужно перегонять (конветритровать) разные типы в друг друга на уровне Модели. Вышестоящие слои это не должно затронуть. И Репозиторию ничего про DataTable знать не нужно. По сути вам нужны методы типа таких:
0
|
26 / 11 / 1
Регистрация: 20.05.2015
Сообщений: 211
|
|
20.11.2022, 00:37 [ТС] | 13 |
Они разные, каждая DataTable уникально по структуре.
Спасибо, поищу. Так вроде о том и весь вопрос. Есть такое желание, просто EF не работает с MS Acess . А Acess крайне удобно для работы без программы (на любом рабочем компе есть офис с которого можно залезть в БД). Я конечно понимаю весь ужас того, что пользователь может что-то поменять в БД вручную, но для моих задач это было очень удобно. Возможно я откажусь от откажусь со временем.
0
|
Модератор
|
|
20.11.2022, 00:42 | 14 |
Есть ещё один нюанс.
Насколько помню в ADO полученные таблицы могут сохранять связь с БД. И на слоях выше, в принципе, в таблицы могут вноситься изменения, которые влияют на логику работы с БД. Если в вашем приложении такое используется, то парсинг в сущности EF значительно затруднится. Добавлено через 2 минуты Не могу точно сказать. Но мен попадался EF даже для XML файлов. Неужeли нет для Access?
0
|
26 / 11 / 1
Регистрация: 20.05.2015
Сообщений: 211
|
|
20.11.2022, 00:54 [ТС] | 15 |
Ну это понятно, пока я такие материи не трогаю (в коде, зачастую, тоже )
Да, о том и вопрос был изначально. Если это можно сделать без рефлексии, то ещё лучше. Добавлено через 8 минут Ну на всяких форумах и Стековерфлоу все прям однозначно писали, что нет. Правда сейчас, неожиданно наткнулся на https://github.com/bubibubi/Je... gration.md , но прям какой-то совсем непопулярный... Но надо будет потыкать, если работает можно и мигрировать потихоньку, хотя, конечно, всё приложение придется перелопатить...
0
|
Модератор
|
|
20.11.2022, 01:03 | 16 |
werymag, рефлексия здесь допустма.
Пример https://stackoverflow.com/a/564373/13349759 В этом примере надо только добавить сохранение полученных рефлексией данных. И следующий раз использовать не рефлексию, а уже сохранённые данные. Сеттеры и Геттеры свойств хранить как делегаты Action и Func<object>. Добавлено через 3 минуты Ну, да. Пять лет уже изменений не вносили. Но как-то неудивительно - использование Access сильно просело. Я даже не знаю в последние версии Офиса она входит? Добавлено через 56 секунд werymag, так же можно поискать пакеты для маршалинга DataTable в коллекции и обратно. Таких думаю будет больше.
0
|
26 / 11 / 1
Регистрация: 20.05.2015
Сообщений: 211
|
|
20.11.2022, 01:04 [ТС] | 17 |
Не используется. В моей супер корявой реализации "модели и VM" данные из модели просто копируются в VM без привязок, и обратно так же передаются в модель, которая уже обновляет БД.
Идея обновлять БД из стандартных методов DataTable мне как-то не понравилась, и создалось впечатление, что она не очень популярна на просторах интернета (возможно мнение ошибочно).
0
|
Модератор
|
|
20.11.2022, 01:13 | 18 |
Тогда проще.
По сути, как понял, на данный момент DataTable используются как DTO. На каком уровне они используются? В Модели, в VM, в View? Добавлено через 2 минуты Раньше это использовалось широко. По сути DataTable и DataSet именно под это и создавались. Но со временем ООП развилось дальше, и стало понятно что такое их использование нарушает принципы ООП на уровне архитектуры приложения. И соответственно ухудшает качество кода. По факту в настоящее время даже в ADO от них потихоньку отказываются в пользу реадеров.
0
|
26 / 11 / 1
Регистрация: 20.05.2015
Сообщений: 211
|
|
20.11.2022, 01:40 [ТС] | 19 |
Нет примера.
Входит. Очередное новое слово для меня, изучу Ух... Из модели я получаю List<DataTable> (функционал DBSet был мне излишен), который я гоняю по всей VM передавая в разные методы и которые открывают кучу всяких окон с самым разнообразным интерфейсом. После окончания работы в окне (после закрытия), изменяется содержимое части DataTable из коллекции. Затем, после штатного закрытия любого окна(связанной с ним VM) и обновления некоторых DataTable, все DataTable имеющие флаг "данные изменились" передаются в модель, через ссылку на объект модели (я понимаю, что это нарушает MVVM, но делать привязки ради этого нет сил) для обновления БД. Наверно такой подход много чего нарушает, но в целом прост и удобен для меня. Концептуально, вместо List<DataTable> можно гонять объект класса со всеми нужными структурами. Добавлено через 4 минуты Внутри VM отдельных окон я с таблицами работаю совершенно по разному (из-за ну очень разных задач), где-то использую клон таблиц, а где-то перегоняю всё в самые разные сущности.
0
|
Модератор
|
|
20.11.2022, 02:07 | 20 |
Там на русский стек была ссылка - её не пропускают.
Заменил на ссылку на английский с подобной темой. Добавлено через 6 минут Ну, я так и понял. DataTable у вас по фактическому использованию - это DTO. В каждой таблице только отражение одной сущности? Или разные строки нужно в разные сущности отражать?
1
|
20.11.2022, 02:07 | |
20.11.2022, 02:07 | |
Помогаю со студенческими работами здесь
20
Наследование,переопределение методов[рефлексия] Какой алгоритм выбрать для меньшего кол-во вызова api-методов? Рефлексия методов с неизвестным массивом параметров Рефлексия. Вывод списка методов, свойств Рефлексия, можно ли получить имена параметров методов Для чего нужна рефлексия при подключении к БД? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи | |||||
Книги и учебные ресурсы по C#
InfoMaster 08.01.2025
Базовые учебники и руководства
Одной из лучших книг для начинающих является "C# 10 и . NET 6 для начинающих" Эндрю Троелсена и Филиппа Джепикса . Книга последовательно раскрывает основные концепции. . .
|
Что такое NullReferenceException и как исправить?
InfoMaster 08.01.2025
NullReferenceException - одно из самых распространенных исключений, с которым сталкиваются разработчики на C#. Это исключение возникает при попытке обратиться к членам объекта (методам, свойствам или. . .
|
Что такое Null Pointer Exception (NPE) и как это исправить?
InfoMaster 08.01.2025
Null Pointer Exception (NPE) - это одно из самых распространенных исключений в Java, которое возникает при попытке использовать ссылку на объект, значение которой равно null. Это исключение относится. . .
|
Русский язык в консоли C++
InfoMaster 08.01.2025
При разработке программ на C++ одной из частых проблем, с которой сталкиваются русскоязычные программисты, является корректное отображение кириллицы в консольных приложениях. Эта проблема особенно. . .
|
Telegram бот на C#
InfoMaster 08.01.2025
Разработка ботов для Telegram стала неотъемлемой частью современной экосистемы мессенджеров. C# предоставляет мощный и удобный инструментарий для создания разнообразных ботов, от простых. . .
|
Использование GraphQL в Go (Golang)
InfoMaster 08.01.2025
Go (Golang) является одним из наиболее популярных языков программирования, используемых для создания высокопроизводительных серверных приложений. Его архитектурные особенности и встроенные. . .
|
Что лучше использовать при создании класса в Java: сеттеры или конструктор?
Alexander-7 08.01.2025
Вопрос подробнее:
На вопрос: «Когда одновременно создаются конструктор и сеттеры в классе – это нормально?» куратор уточнил: «Ваш класс может вообще не иметь сеттеров, а только конструктор и геттеры. . .
|
Как работать с GraphQL на TypeScript
InfoMaster 08.01.2025
Введение в GraphQL и TypeScript
В современной разработке веб-приложений GraphQL стал мощным инструментом для создания гибких и эффективных API. В сочетании с TypeScript, эта технология. . .
|
Счётчик на базе сумматоров + регистров и генератора сигналов согласования.
Hrethgir 07.01.2025
Создан с целью проверки скорости асинхронной логики: ранее описанного сумматора и предополагаемых fast регистров. Регистры созданы на базе ранее описанного, предполагаемого fast триггера. То-есть. . .
|
Как перейти с Options API на Composition API в Vue.js
BasicMan 06.01.2025
Почему переход на Composition API актуален
В мире современной веб-разработки фреймворк Vue. js продолжает эволюционировать, предлагая разработчикам все более совершенные инструменты для создания. . .
|
Архитектура современных процессоров
inter-admin 06.01.2025
Процессор (центральный процессор, ЦП) является основным вычислительным устройством компьютера, которое выполняет обработку данных и управляет работой всех остальных компонентов системы. Архитектура. . .
|
История создания реляционной модели баз данных, правила Кодда
Programming 06.01.2025
Предпосылки создания реляционной модели
В конце 1960-х годов компьютерная индустрия столкнулась с серьезными проблемами в области управления данными. Существовавшие на тот момент модели данных -. . .
|