#c# #sql #fluent-nhibernate #many-to-many
#c# #sql #свободно-nhibernate #многие-ко-многим #многие ко многим
Вопрос:
Я создаю веб-службу WCF и сопоставляю свою доменную модель с использованием Fluent Nhibernate, и я заметил, что объекты могут быть представлены по-разному, как и данные, стоящие за ними.
По сути, у меня есть три таблицы: одна — таблица собраний, одна — таблица мест собраний, а другая — таблица участников. В принципе, приложение будет работать таким образом, что собрание будет назначено, и участники пойдут, но они также будут голосовать за Место проведения. Таким образом, в основном на многих собраниях много участников, и многие участники имеют много голосов (при условии, что установлено ограничение, так что у них есть только один голос на собрание. Это выглядит так. Итак, чтобы представить это, у меня есть три базовые таблицы и Многие Ко многим (ко многим? Таблица)
CREATE TABLE Meetings (
Id INT NOT NULL PRIMARY KEY IDENTITY,
Name NOT NULL,
StartTime DATETIME NOT NULL,
EndTime DATETIME NULL,
)
CREATE TABLE Attendees (
Id INT NOT NULL PRIMARY KEY IDENTITY,
Name NOT NULL
)
CREATE TABLE MeetingPlaces (
Id INT NOT NULL PRIMARY KEY IDENTITY,
Name NOT NULL,
Address NULL
)
CREATE TABLE MeetingAttendees (
Id INT NOT NULL PRIMARY KEY IDENTITY,
MeetingId INT NOT NULL,
AttendeeId INT NOT NULL,
MeetingPlaceId INT NULL, --in case they have no preference
CONSTRAINT FK_MeetingAttendees_To_Events FOREIGN KEY (MeetingId) REFERENCES Meetings(Id),
CONSTRAINT FK_MeetingAttendees_To_Attendees FOREIGN KEY (AttendeeId) REFERENCES Attendees(Id),
CONSTRAINT FK_MeetingAttendees_To_MeetingPlaces FOREIGN KEY (MeetingPlaceId) REFERENCES MeetingPlaces(Id)
)
GO
CREATE UNIQUE INDEX U_IDX_Meeting_Attendees ON MeetingAttendees(MeetingId, AttendeeId)
GO
Мой вопрос в том, что лучше использовать эту структуру или создать две отдельные таблицы. Одна представляет участников собрания, а другая представляет голосование участника за участников собрания как таковое:
CREATE TABLE MeetingAttendees
Id INT NOT NULL PRIMARY KEY IDENTITY,
MeetingId INT NOT NULL,
AttendeeId INT NOT NULL,
CONSTRAINT FK_MeetingAttendees_To_Events FOREIGN KEY (MeetingId) REFERENCES Meetings(Id),
CONSTRAINT FK_MeetingAttendees_To_Attendees FOREIGN KEY (AttendeeId) REFERENCES Attendees(Id),
)
GO
CREATE UNIQUE INDEX U_IDX_Meeting_Attendees ON MeetingAttendees(MeetingId, AttendeeId)
CREATE TABLE AttendeeVote(
Id INT NOT NULL PRIMARY KEY IDENTITY,
MeetingAttendeeId INT NOT NULL,
MeetingPlaceId INT NULL,
CONSTRAINT FK_AttendeeVote_To_MeetingAttendees FOREIGN KEY (MeetingAttendeeId) REFERENCES MeetingAttendees(Id),
CONSTRAINT FK_AttendeeVote_To_MeetingPlaces FOREIGN KEY (MeetingPlaceId) REFERENCE MeetingPlaces(Id)
)
Я обеспокоен, потому что я не уверен, насколько Fluent-NHibernate справится с первым решением, а второе, хотя и немного надуманное, кажется более конструктивным.
Ответ №1:
У вас должна быть ассоциативная сущность между каждым отношением «многие ко многим».
Если я правильно понимаю ваш случай:
- Собрание (информация о собрании)
- Участник (информация об участнике)
- MeetingVote (meeting_id, attendee_id, дополнительная информация)
- MeetingAttendee (meeting_id, attendee_id, дополнительная информация)
Это было бы нормализовано и правильно отображало поведение вашего приложения.
Некоторые утверждают, что если это приложение читает более 90% времени, вам следует отменить нормализацию, но если вы регулярно читаете и пишете, у вас должно быть два отдельных ассоциативных объекта.
Комментарии:
1. В перечисленных вами случаях MeetingVote и MeetingAttendee совпадают, не уверен, что вы видите MeetingVote в вашем примере.
2. Возможно, я неправильно понял ваш вопрос. Таблица MeetingVote будет представлять, когда человек проголосовал за собрание? MeetingAttendee будет представлять, когда кто-то посещал собрание.
3. О, извините, голосование на собрании должно быть голосованием участников. Это когда участник (для собрания) голосует за место, где должно состояться собрание. Таким образом, собрание, участник и место связаны друг с другом моим первым решением.
4. Ааа, хорошо. Предположение, которое я вижу при использовании только одного вспомогательного объекта, заключается в том, что участник должен присутствовать и голосовать за место. Правильно ли это?
5. На самом деле, отличный момент, я полностью пропустил это. Я думаю, что участнику не обязательно идти на собрание, он действительно должен быть «Участником», и их классификация как участника зависит от ассоциативной таблицы. Я полагаю, я могу создать первую ассоциативную таблицу между участниками собрания в качестве участников собрания, тогда вторая будет между участниками собрания и местоположениями в качестве участников собрания. Таким образом, посещение собрания может быть необязательным, и я могу ограничить участника, который принимает участие в одном голосовании, уникальным индексом. Это кажется разумным?