#c# #fluent-nhibernate
#c# #свободно-nhibernate
Вопрос:
У меня есть два класса User и Appointment, которые раньше были связаны отношением «многие ко многим». Но теперь я должен иметь возможность управлять состоянием этого отношения (мне нужно иметь возможность отслеживать, принял ли пользователь назначение, отклонил или еще не ответил).
Классы сопоставляются с соответствующими таблицами Users и Appointments. Обе таблицы связаны через таблицу назначений пользователей, которая имеет составной первичный ключ, состоящий из fk для пользователей и fk для таблицы назначений.
Текущая реализация выдает исключение с сообщением: «Недопустимый индекс 2 для этого SqlParameterCollection с Count=2″. когда я пытаюсь добавить НОВЫЙ объект назначения пользователя в коллекцию объекта назначения
Отображение пользователя
public class UserMap : ClassMap<User>
{
public UserMap()
{
Id(d => d.Id);
Map(d => d.FirstName).Column("FirstName");
Map(d => d.LastName).Column("LastName");
Map(d => d.Email).Column("Email");
HasMany(u => u.UserAppointments);
Table("Users");
}
}
Сопоставление назначений
public class AppointmentMap : ClassMap<Appointment>
{
public AppointmentMap()
{
Id(c => c.Id);
HasMany(a => a.AppointmentParticipants).Inverse().Cascade.All();
References(a => a.Location).Column("FkAddressId");
Map(a => a.DateAndTime).Column("AppointmentDate").CustomType<UtcDateTimeType>();
Map(a => a.Description).Column("AppointmentDescription");
Map(a => a.Status).Column("AppointmentStatus").CustomType<AppointmentStatus>();
HasMany(a => a.AppointmentEstates).Inverse().Cascade.All();
Table("Appointments");
}
Сопоставление пользовательских назначений
public class UserAppointmentsMap : ClassMap<UserAppointment>
{
public UserAppointmentsMap()
{
CompositeId()
.KeyReference(a => a.Appointment, "FkAppointmentsId")
.KeyReference(u => u.User, "FkUserId");
References(a => a.User).Column("FkUserId");
References(a => a.Appointment).Column("FkAppointmentsId");
Table("UserAppointments");
}
}
Ожидаемый результат заключается в том, что когда я добавляю новое назначение пользователя в коллекцию существующего назначения, в таблице назначений пользователей создается новая запись, указывающая на соответствующий объект User и Appointment
Ответ №1:
Мне наконец удалось решить проблему…. На самом деле было несколько проблем с моим кодом:
-
Проблема с «Недопустимым индексом 2 для этого SqlParameterCollection с Count = 2».было вызвано UserAppointmentsMap. После определения свойства как части составного ключа его не следует повторно отображать в качестве ссылки.
public class UserAppointmentsMap : ClassMap<UserAppointment> { public UserAppointmentsMap() { CompositeId() .KeyReference(a => a.Appointment, "FkAppointmentsId") .KeyReference(u => u.User, "FkUserId"); Table("UserAppointments"); } }
-
Составной идентификатор с внешним ключом должен выполняться с помощью KeyReference вместо KeyProperty
-
У меня возникла проблема с неправильно сгенерированным запросом (внешний ключ был неправильным, т.Е. Вместо FkAppointmentsId он искал Appointments_Id), поэтому мне пришлось явно указать имя столбца
public class AppointmentMap : ClassMap<Appointment> { public AppointmentMap() { Id(c => c.Id); HasMany(a => a.AppointmentParticipants).Inverse().KeyColumn("FkAppointmentsId").Cascade.All(); References(a => a.Location).Column("FkAddressId"); Map(a => a.DateAndTime).Column("AppointmentDate").CustomType<UtcDateTimeType>(); Map(a => a.Description).Column("AppointmentDescription"); Map(a => a.Status).Column("AppointmentStatus").CustomType<AppointmentStatus>(); HasMany(a => a.AppointmentEstates).Inverse().KeyColumn("FkAppointmentsId").Cascade.All(); Table("Appointments"); } }