|
0 / 0 / 1
Регистрация: 19.05.2017
Сообщений: 39
|
||||||||||||||||||||||||||
[EntityFramework] Не работает обновление БД (связь многие-ко-многим)28.10.2021, 17:22. Показов 5815. Ответов 49
Метки нет (Все метки)
Здравствуйте. Копаюсь с этой проблемой уже пол дня и в упор не замечаю проблему, поэтому пишу сюда.
Есть 2 модели: User (пользователь) и Stock (акция). Одному пользователю может соответствовать множество акций, а одной акции - множество пользователей, соответственно Entity Framework создает в БД 3 таблицы. По какой-то причине, когда я пытаюсь привязать акцию к конкретному пользователю, в моей БД не происходит никаких обновлений. Хотя, судя по отладке, везде передаются правильные значения, а также вызывается необходимый метод репозитория. User:
Команда для добавления акции к пользователю:
Акции то добавляются, то не добавляются, то вылетает ошибка (что запись с таким id уже существует), поэтому я вообще не могу понять в чем заключается моя ошибка. Заранее спасибо за помощь.
0
|
||||||||||||||||||||||||||
| 28.10.2021, 17:22 | |
|
Ответы с готовыми решениями:
49
Обновление данных таблицы на основе запроса (связь многие-ко-многим) Не работает связь многие ко многим |
|
Модератор
|
||||||||||||
| 28.10.2021, 18:27 | ||||||||||||
_dbContext и this._StocksRepositor.1) В EF DbContext - это средство создания SQL запроса к БД. И к нему надо относится как к одной единой транзакции. А у вас, похоже, он создаётся на всё время сеанса приложения. Должно быть: Создали, задали параметры запроса, материализовали запрос, уничтожили. И всё это лучше делать в блоке юсиннга:
2) Запросы к БД надо делать сразу по нужным параметрам, а не извлекать оттуда всю БД и потом фильтровать полученные данные. Если вы реализуете репозиторий, то соответствующие параметры на передать в метод Репозитория, где он сформирует нужный запрос и вернёт только те данные, которые соответствуют заданным параметрам. Чё-то подобное:
0
|
||||||||||||
|
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
|
||||||
| 28.10.2021, 18:58 | ||||||
|
Связь многие-ко-многим реализуется через третью таблицу - т.н. "кросс-таблицу" или таблицу ссылок. У Вас ее, очевидно, нету. И вы городите ерунду, пытаясь связать ужа с ежом.
Надо так:
0
|
||||||
|
0 / 0 / 1
Регистрация: 19.05.2017
Сообщений: 39
|
|||||
| 28.10.2021, 19:14 [ТС] | |||||
|
Добавлено через 3 минуты Спасибо за замечания, но пока они не приблизили меня к ответу
0
|
|||||
|
Модератор
|
|||
| 28.10.2021, 19:41 | |||
|
В EF контекст DB - это она транзакция. Читайте Время существования. Если вы работаете с контекстом непосредственно в Форме или Окне, то вы можете создать контекст на всё время жизни Окна или Формы. Но вы работаете с БД через Репозиторий. А Репозиторий понятия не имеет сколько Окон или Форм его используют. И, с другой стороны, если работа с данными в Формах, хоть и выгляди коряво, часто реализуется в Code Behind, то в WPF желательно Code Behind, вообще, не трогать. А для работы с Данными - это и вовсе недопустимо. Поэтому по указной ссылке к вашей задаче и имеющейся реализации относятся все пункты кроме этого. И из всех них следует, что контекст должен создаваться только на время запроса. Добавлено через 1 минуту По показанному вами коду невозможно сделать выводы о причинах проблемы. Ну, или моих знаний для этого не хватает - я не большой дока по БД,
0
|
|||
|
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
|
|||
| 28.10.2021, 22:05 | |||
|
0
|
|||
|
0 / 0 / 1
Регистрация: 19.05.2017
Сообщений: 39
|
||||||||||||||||||||||||
| 28.10.2021, 23:49 [ТС] | ||||||||||||||||||||||||
0
|
||||||||||||||||||||||||
|
Модератор
|
|||||||||||||||||
| 29.10.2021, 00:44 | |||||||||||||||||
|
Но примерно такая должна быть реализация:
0
|
|||||||||||||||||
|
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
|
|
| 29.10.2021, 00:47 | |
|
nranes, Для каждой модели свой репозиторий, и при этом есть еще и контекст EF. И все это для "базы" из двух сущностей.
Конгениально ! Просто нет слов.
0
|
|
|
Модератор
|
||
| 29.10.2021, 01:19 | ||
|
Реализация шаблонов репозитория и единиц работы в приложении ASP.NET MVC (9 из 10); Применение пользовательского репозитория по сравнению с непосредственным применением DbContext EF; Если вы в Модели оперируете EF сущностями (отражающими данные БД), то смысла в создании отдельной реализации репозитория не много. DbContext и так его уже реализует. Такое имеет смысл только в учебных целях. Если же в Модели у вас есть Бизнес Логика и в ней используются какие-то свои сущности (Бизнес сущности), то Репозиторий будет выполнять задачу абстрагирования от Хранилища. И в таком случае Модель и Репозиторий должны обмениваться не EF сущностями, а Бизнес сущностями. EF сущности должны быть инкапсулированы на уровне Репозитория. Если это часть паттерна MVVM, то обмен данными ViewModel <-> Модель лучше осуществлять в DTO типах (сейчас их роль с успехом выполняют кортежи и записи). И в Модели должен быть ещё мапинг между DTO типами и Бизнес сущностями (или EF сущностями).
0
|
||
|
|
|||||||
| 29.10.2021, 01:32 | |||||||
И контекст в EF используется не только для создания запросов, но еще и для мониторинга изменений. А как он будет мониторить изменения, если его каждый раз удалять?
1
|
|||||||
|
Модератор
|
|||
| 29.10.2021, 02:18 | |||
|
Andrey-MSK, я небольшой спец по этим вопросам.
Поэтому отвечу на уровне своих знаний - может и неверных. В EF DbContext предоставляет IQueryable посредством, которого можно делать SQL запросы, используя более привычный для Шарпа синтаксис LINQ. До тех пор пока IQueryable не материализуется - это просто выражение. Транслируется в запрос он только в момент материализации. Наверное, существуют задачи где в запросе используются 50 таблиц, но мне это трудно себе представить. Так же в данной теме речь идёт о реализации паттерна Репозиторий. Выше я давал пару ссылок. В этом паттерне желательно создавать отдельные узлы агрегации для каждой сущности (надеюсь я правильно использую терминологию) и, фактически, в такой реализации в каждом запросе происходит работа только с одной таблицей. Что касается соединения с БД - не совсем уверен, но мне представляется, что оно создаётся при первом обращении к БД через DbContext (обычно оно очень длительное) и сохраняется какое-то длительное время. По ощущениям (специально не тестировал) на всё время сеанса приложения. Я, конечно, ни сколько не оспариваю того, что существуют сложные задачи по работе с БД которые не укладываются в эту схему. Но EF не нацелен на такие сложные задачи. Их надо решать другими инструментами. Добавлено через 10 минут
1
|
|||
|
|
|
| 29.10.2021, 02:44 | |
|
Элд Хасп, А вот теперь смотрите. У вас работает сервер приложений, который предоставляет доступ к БД множеству пользователей через своё, одно-единстенное, соединение. Куча пользователей сохраняет, удаляет, модифицирует данные, и вы думаете что для каждого запроса пользователя будет создаваться отдельный контекст для работы с БД? Нет, контекст один для всех, он полностью управляет всей достоверностью данных. Зачем каждый раз перечитывать новые данные из БД, когда проще и быстрее их взять из контекста, который всё это отследил и сохранил у себя.
Тут много вариантов на эту тему. Ведь EF в основном и создавался для WEB и серверов приложений. Это потом его уже начали тащить в локальные приложения, тут да, если приложение работает само по себе, то и отслеживание изменений по идее не нужно, но опять же, лишний раз грузить данные из БД такое себе, проще взять из контекста. Да есть и минусы, один из них расход памяти на это всё дело, но для серверов это не особо критично. Может я где и ошибаюсь, но это лично моё мнение и оно не претендует на единственно правильное ![]() Добавлено через 9 минут Элд Хасп, Из вашей ссылки Это означает, что удаление DbContext — это обычный способ остановки отслеживания сущностей. Вот в принципе то, что я и писал выше.
1
|
|
|
Модератор
|
|||
| 29.10.2021, 09:48 | |||
|
Так и есть. И опять таки мы, в данной теме, рассуждаем о реализации ООП паттернов приложений MVC/MVP/MVVM, в которых на уровне Модели ещё присутствует и разделение на слои с Бизнес Логикой и Репозиторий. В них Модель с Репозиториями обмениваются Бизнес Сущностями. И в такой реализации нет потребности в отслеживании EF сущностей после их мапинга в Бизнес Сущности. Из всех примеров и учебников по его (EF) использованию, применению, вроде, как бы наоборот, он предназначен для локальных клиентов. И рассчитан, в первую очередь, на тех программистов, которые знают Шарп, но не знают (или плохо знают) SQL - чего определённо нельзя сказать про тех кто создаёт сервера.
1
|
|||
|
|
||
| 29.10.2021, 09:53 | ||
|
Одна команда морду лепит, вторая базами данных занимается, третья всё это склеивает друг с другом
1
|
||
|
0 / 0 / 1
Регистрация: 19.05.2017
Сообщений: 39
|
|||
| 29.10.2021, 10:05 [ТС] | |||
|
MsGuns,
Я естественно не могу ничего сказать на этот счет, так как только недавно начал активно разбираться в этой теме и мои недочеты в реализации абсолютно естественны.
0
|
|||
|
|
||
| 29.10.2021, 10:20 | ||
|
Ну а про две. Вы же его планы не знаете, может быть проект должен разрастись на большее количество. И вообще. Не каждый может
1
|
||
|
0 / 0 / 1
Регистрация: 19.05.2017
Сообщений: 39
|
|
| 29.10.2021, 11:09 [ТС] | |
|
Проблема до сих пор не решена.
Периодически акции добавляются нормально, но иногда вылетает очень странная ошибка: MySqlException: Duplicate entry '5-1' for key 'PRIMARY' Смысл мне, естественно, понятен, но как такое может быть - вообще не понимаю. В промежуточной таблице уже есть запись 5-1 (StockId-UserId), а я пытаюсь туда добавить еще одну акцию с Id=7 для пользователя с Id=1. Также, когда я, например, использую метод Update() репозитория, передавая туда нового User, меняются все поля кроме самого списка акций (то есть, если я сделаю Update() и поменяю имя пользователя, то оно поменяется, но если я поменяю список акций, которые ему принадлежат - они могут не добавиться в промежуточную таблицу). У меня создается впечатление, что тут дело не в моих репозиториях, а в настройках промежуточной таблицы, которую автоматически создает EF.
0
|
|
| 29.10.2021, 11:14 | |||||||
0
|
|||||||
| 29.10.2021, 11:14 | |
|
Помогаю со студенческими работами здесь
20
Entity Framework 6. Code First. Связь один-ко-многим и многие-ко-многим одновременно Заполнение таблицы с отношением многие ко многим (EntityFramework) Связь один ко многим или многие к многим Связь многие ко многим
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога
Финальные проекты на Си и на C++:
finish-rectangles-sdl3-c. zip
finish-rectangles-sdl3-cpp. zip
|
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие.
Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
|
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ВВЕДЕНИЕ
Выполняя задание на управление насосной группой заполнения резервуара,. . .
|
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
|
|
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога
Финальные проекты на Си и на C++:
hello-sdl3-c. zip
hello-sdl3-cpp. zip
Результат:
|
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога
MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
|
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд.
Даже если у вас. . .
|
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает
монорепозиторий в котором находятся все исходники.
При создании нового решения, мы просто добавляем нужные проекты
и имеем. . .
|