Что я пытаюсь сделать
Я моделирую приложение, в котором люди (участники) участвуют в беседе, где у каждого из них есть список тегов, которые определяют их причины для разговора.
Пример
Алиса является участником беседы, и она помечена как автор определенного коммита, а Боб помечен как рецензент этого коммита.
Ограничения
- Участник имеет коллекцию тегов
- Нет двунаправленных ассоциаций, поэтому Класс тегов не знает об участниках (Двунаправленные ассоциации сложнее управлять в коде модели домена)
- Теги должны быть сохранены в отдельной таблице с составным PK, состоящим из 3 значений (ParticipantId, EntityId, TypeId)
Задача
Я не могу настроить NHibernate, используя свободное отображение, чтобы включить столбец ParticipantId (который также является FK) как часть составного PK в таблице тегов.
Почему составной ключ, а не суррогатное автоинкрементное удостоверение?
Таблица тегов, как ожидается, будет содержать много данных, которые будут сильно
запрос.
В таблице тегов не должно быть повторяющихся записей
Итак, в любом случае необходимо создать уникальный индекс по 3 свойствам (ParticipantId, EnitityId, TagId), так зачем дублировать данные?
Почему бы просто не использовать CompositeId (). KeyReference?
Как упоминалось выше, я хотел бы избежать двунаправленных ассоциаций.
В доменной модели:
Participant
имеет коллекцию Tag
с.
Tag
с не знают о Participant
.
Таким образом, класс Tag
даже не имеет свойства Participant
, поэтому его нельзя использовать в KeyReference
.
Объекты выглядят как показано ниже
public class Participant : IEquatable<Participant>
{
private int _id;
private IList<Tag> _tags = new List<Tag>();
public virtual int Id => _id;
public virtual IReadOnlyCollection<Tag> Tags => new ReadOnlyCollection<Tag>(_tags);
// omitted for brevity
}
public class Tag : IEquatable<Tag>
{
private byte _typeId;
private int _entityId;
public virtual byte TypeId => _typeId;
public virtual int EntityId => _entityId;
// omitted for brevity
}
Вот беглое отображение
public class ParticipantMapping : ClassMap<Participant>
{
public ParticipantMapping()
{
Id(x => x.Id);
HasMany(x => x.Tags);
}
}
public class TagMapping : ClassMap<Tag>
{
public TagMapping()
{
CompositeId()
.KeyProperty(x => x.EntityId)
.KeyProperty(x => x.TypeId);
//.KeyReference(x => x.Participant);
}
}
Когда я использую сопоставление NHibernate для создания схемы, я получаю следующее, в котором отсутствует ParticipantId как часть составного PK
CREATE TABLE [dbo].[Tags](
[EntityId] [int] NOT NULL,
[TypeId] [tinyint] NOT NULL,
[ParticipantId] [int] NULL,
PRIMARY KEY CLUSTERED
(
[EntityId] ASC,
[TypeId] ASC,
-- MISSING THIS : [ParticipantId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Tags] WITH CHECK ADD CONSTRAINT [FK2B61AAB3E2880CD5] FOREIGN KEY([ParticipantId])
REFERENCES [dbo].[Participants] ([Id])
GO
ALTER TABLE [dbo].[Tags] CHECK CONSTRAINT [FK2B61AAB3E2880CD5]
GO
Я использую FluentNhibernate v 2.1.2
<PackageReference Include="FluentNHibernate" Version="2.1.2" />