Форум программистов, компьютерный форум, киберфорум
C#: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
0 / 0 / 0
Регистрация: 08.07.2021
Сообщений: 18

Связь "Многое ко многим"

07.08.2021, 21:57. Показов 3626. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, уважаемые программисты!
Я создал базу данных, где хранятся данные о клиентах, товарах и заказах. Также создал промежуточно таблицу для накопление товаров в заказе. У меня выдается ошибка, когда я пытаюсь осуществить связь "многое ко многим", и суть этой ошибки в том что я пытаюсь записать пустой первичный ключ во внешний ключ промежуточной таблицы. А так нельзя, надо чтобы у родительской таблицы был ключ, чтобы дочерняя таблица могла ссылаться. В связи с этим у меня возник вопрос, как это лучше сделать?
Я могу сначала ввести в таблицу заказы(основная таблица) ключ через "Insert", потом заполнить таблицу покупки (промежуточная таблица), и потом через "update" обновить поля в таблице заказов для этого заказа, так будет нормально или можно проще и лучше ?

0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.08.2021, 21:57
Ответы с готовыми решениями:

Entity Framework 6. Code First. Связь один-ко-многим и многие-ко-многим одновременно
Здрасти. Есть таблица юзеров и объявлений. У юзера может быть множество объявлений. Здесь действует связь один-ко-многим. Но юзер также...

Связь один ко многим
Как сделать данную связь? Чтобы при выборе значения в комбобоксе, показывалось 3 значения. А именно при выборе отдела, должно выводится в...

Связь многие ко многим, выборка
Есть 2 таблицы которые реализую связь многие ко многим: Фильмы и Жанры public class Film { public int Id { get; set; } ...

15
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
08.08.2021, 00:23
Тут нет связи "многие-ко-многим".
Order имеет ссылку только на одного клиента.
В свою очередь состав заказа (спецификация) Procurements ссылается на заказ и на товар (Products).

Т.е. каждый заказ имеет несколько товаров, но лишь одного покупателя.
Соответственно цена и количество должны быть в записях о конкретном товаре в таблице состава.
В самой записи заказа может присутствовать вычисляемое поле "Сумма заказа" и, если нужно, кол-во позиций (записей состава по заказу.

Связи многие-ко-многим тут нет.

При оформлении нового заказа Вы можете сначала добавлять в таблицу заказов и, получив id новой записи, делать привязку записей грида с составом к его Id (первый Select вернет естественно 0 записей и грид будет пуст).
При добавлении каждого нового товара в Insert будет передаваться Id заказа как Foreign Key и все будет нормально инсертиться, а после перечитки гридного датасета новая запись с только что добавленным товаром отобразится.
Добавление товара можно сделать как в самом гриде (технически это сложнее из-за необходимости ловить события грида для проверки введенного), так и в модальной формочке (проще и надежнее).
Вычисляемые поля (Сумма и число позиций) можно вообще не хранить в базе из-за ненужности, а вычислять их каждый раз при извлечении состава заказа.

Добавлено через 9 минут
И еще по сути решаемой задачи касатально цены на товар.
1. Цен на товар может быть несколько (опт, мелкий опт, розница, акция, цена со скидкой VIP и т.д.). Обычно в базе есть еще одна таблица - таблица прайсов.
2. Вместо цены в составе заказа следует иметь поля "скидка" и "цена по прайсу", из которых вычисляется поле "отпускная цена".
3. Нужно еще поле "ставка НДС" и "сумма НДС". Они нужны для фискального учета. В частности, для чеков и бухгалтерии.

Поля "суммарная скидка" и "сумма НДС по заказу" могут также присутствовать в записи заказа, но это в случае если там же и общая отпускная сумма по заказу. Они хоть являются автовычисляемыми, но в базе могут храниться. Хотя бы для того, чтобы быстрее получать аналитику по продажам.

Добавлено через 11 минут
Я подумал-подумал и:
Второй абзац можете проигнорировать, если Вы создаете примитивную систему продаж.
Но если это серьезный проект для конкретного магазина, то для нормальной системы учета в базу нужно добавлять много новый сущностей и соответственно связанных между собою таблиц. В частности, нужны таблицы для товаров (карточки товара), таблицы приходно-расходных документов, привязка к бухгалтерии (счета/субсчета, операции, проводки и т.д.), таблица групп товаров, справочник поставщиков и договоров с ними и много еще чего - всего таблиц 20-30. И это минимум
1
0 / 0 / 0
Регистрация: 08.07.2021
Сообщений: 18
08.08.2021, 12:10  [ТС]
Ого, спасибо вам за подробный экскурс!
Хотелось бы спросить кое-что, у меня была идея создание связи "многое ко многому" для таблиц Orders и Products. Эту связь я осуществил через Procurements. Исходя из этого, почему у меня нету связи "многое ко многому"? Я же всё правильно делаю ? Или вы имели ввиду что нету этой связи между таблицами Orders и Clients? В силу того что один человек может иметь несколько заказов и один заказ может принадлежать нескольким людям.
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
10.08.2021, 19:09
Цитата Сообщение от I_am_the_One Посмотреть сообщение
В силу того что один человек может иметь несколько заказов и один заказ может принадлежать нескольким людям.
Если так, то это именно "многие-ко-многим". Но я не предполагал, что "один заказ может принадлежать нескольким людям".
0
0 / 0 / 0
Регистрация: 08.07.2021
Сообщений: 18
10.08.2021, 19:27  [ТС]
Так у меня и нету связи между клиентами и заказами, у меня связь "многое ко многим" между заказами и товарами. Но вы сказали что у меня нет этой связи. Я так и не понял почему ? Я же всё правильно делаю. В нескольких заказах может быть один и тот же товар и несколько товаров могут быть в одном и том же заказе. Эту идею я и сделал с помощью внешних ключей в таблице procurements. Что не так ?
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
10.08.2021, 21:09
Цитата Сообщение от I_am_the_One Посмотреть сообщение
у меня связь "многое ко многим" между заказами и товарами
Откуда ? Один заказ-много товаров. Все.
Если надо посмотреть в каких заказах использовался какой-то товар, то это делается простым запросом.
То же самое с клиентами.
Просто у Вас нет правильной схемы. Товар - состав заказа - заказ.
1. Таблица товаров
2. Таблица клиентов
3. Таблица заказов со ссылкой на клиента
4. Таблица состава заказов, в каждой записи которой ссылка на товар и на заказ.

Добавлено через 40 секунд
Фактически товары и клиенты используются как справочники.
0
Эксперт .NET
 Аватар для Usaga
14313 / 9393 / 1355
Регистрация: 21.01.2016
Сообщений: 35,424
11.08.2021, 05:26
Цитата Сообщение от MsGuns Посмотреть сообщение
Откуда ? Один заказ-много товаров. Все.
Всё он верно говорит. Многие ко многим. В один заказ входит несколько товаров. Но один товар может участвовать в нескольких заказах. Всё верно.
1
0 / 0 / 0
Регистрация: 08.07.2021
Сообщений: 18
11.08.2021, 08:17  [ТС]
Тогда я возвращаюсь к начальному вопросу. У меня выдается ошибка, когда я пытаюсь осуществить связь "многое ко многим", и суть этой ошибки в том что я пытаюсь записать пустой первичный ключ во внешний ключ промежуточной таблицы. А так нельзя, надо чтобы у родительской таблицы был ключ, чтобы дочерняя таблица могла ссылаться. В связи с этим у меня возник вопрос, как это лучше сделать?
Я могу сначала ввести в таблицу заказы(основная таблица) ключ через "Insert", потом заполнить таблицу покупки (промежуточная таблица), и потом через "update" обновить поля в таблице заказов для этого заказа, так будет нормально или можно проще и лучше ?
0
Эксперт .NET
 Аватар для Usaga
14313 / 9393 / 1355
Регистрация: 21.01.2016
Сообщений: 35,424
11.08.2021, 08:20
I_am_the_One, вообще, сначала вносятся в базу родительские записи (на которые "многие-ко-многим" будут ссылаться), а потом уже между ними связь строится.
1
 Аватар для Andrey-MSK
3353 / 2239 / 388
Регистрация: 14.08.2018
Сообщений: 7,569
Записей в блоге: 4
11.08.2021, 08:34
I_am_the_One,
1. В таблицу Procurements нужно добавить первичный ключ.
2. При оформлении заказа в эту таблицу вставлять пары OrderID + ProductID.
3. После этого запросом можно будет вытащить товары и заказы в которые они входят.
1
0 / 0 / 0
Регистрация: 08.07.2021
Сообщений: 18
11.08.2021, 09:30  [ТС]
Спасибо всем кто помог
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
11.08.2021, 11:49
Цитата Сообщение от Usaga Посмотреть сообщение
Всё он верно говорит. Многие ко многим. В один заказ входит несколько товаров. Но один товар может участвовать в нескольких заказах. Всё верно.
Нет, не так. При "м-к-м" требуется таблица перекрестных ссылок. Например, есть детки в школе и "кружки по интересам" в школе. Каждый ребенок может посещать несколько кружков, в каждом кружке может быть несколько детей. Для построения связей нужна таблица перекрестных ссылок.
В случае с накладными (заказами) сабжа такой связи нету. Обычная связь одна накладная - много товаров. Все прекрасно работает без всяких дополнительных таблиц.

Добавлено через 7 минут
Поясню. Сама по себе таблица "Заказ" никак не связана и с какими товарами, а вот связанная с этой таблицей отношением о-к-м другая таблица "Состав заказов" (спецификация, фактура, список и т.д.) связана с таблицей "Товары" отношением о-к-о (два товара не может быть в одной записи состава). Вроде бы м-к-м смыслово (заказ-товар), но реляционно - нет, т.к. таблицы перекрестных ссылок нет, а ее роль выполняет вполне себе сущностная (реальная) таблица состава.

Добавлено через 3 минуты
А вот если убрать таблицу состава и обойтись только двумя таблицами "Заказ" и "Товар", то тогда действительно будет
м-к-м и при этом нужна перекрестная таблица, в которую еще придется писать кол-во, цена и т.д. Т.е. по сути она будет выполнять роль связки и деталей. Но это не правильный подход - таблица состава нужна.
0
Эксперт .NET
 Аватар для Usaga
14313 / 9393 / 1355
Регистрация: 21.01.2016
Сообщений: 35,424
11.08.2021, 12:45
MsGuns, так ваша таблица состава и есть таблица связей. Одна сущность) И никто вам не мешает по мимо этих связей ещё и дополнительную информацию там держать.
0
0 / 0 / 0
Регистрация: 08.07.2021
Сообщений: 18
11.08.2021, 12:53  [ТС]
Я так и решил сделать
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
11.08.2021, 13:19
Цитата Сообщение от Usaga Посмотреть сообщение
так ваша таблица состава и есть таблица связей. Одна сущность) И никто вам не мешает по мимо этих связей ещё и дополнительную информацию там держать.
Ну, в общем Вы правы Насколько я помню теорию (давно читал Дейта), таблица перекрестных ссылок - сама по себе такой же суррогат, как и id, т.е.ничего, кроме ссылок, не содержит. Фактура же - часть реального документа, т.е. содержит сущности + дополнительную реальную информацию, поэтому как бы не является "классической" перекрестной таблицей ссылок.
Ну как-то так
1
Эксперт .NET
 Аватар для Usaga
14313 / 9393 / 1355
Регистрация: 21.01.2016
Сообщений: 35,424
11.08.2021, 13:29
MsGuns, я понял. Вы предложили разделить суррогатную таблицу от таблицы выражающей сущность. Если так смотреть на проблему, то да - это не одно и тоже. Но я бы не стал так сильно упарываться)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
11.08.2021, 13:29
Помогаю со студенческими работами здесь

Связь один ко многим. EF Core
Добрый вечер. У меня есть класс public class New : EntityBase { public DateTime CreatedDate { get; set; } ...

Связь многие ко многим EntityFramework Code First
Всем привет! Столкнулся с проблемой при проектировании БД со связью многие-ко-многим. Ситуация следующая: есть врачи и есть мед....

Связь многие-ко-многим в Entity Framework
делаю задания с моделями сущностей entity framework. на примере студентов и курсов, у каждого студента может быть несколько курсов, как и у...

Связь многие ко многим (Entity Framework)
Мне нужна связь многие ко многим. Нашел вот тут хороший туториал который объясняет как ее сделать на Entity Framework. Но не понятно что...

linq2db связь многие ко многим (many-to-many Association)
Всем привет!!! Есть три сущности `Course` - курсы `Category` - категории `Tag` - теги Один курс может быть одновременно в...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита, которое может. . .
Команды "Заполнить" и "Очистить" на форме документа
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". На примере нетипового документа разработанного в конфигурации КА2. В качестве источника данных указан регистр накопления, в который записываются данные о. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru