Невозможно настроить составной первичный ключ, включающий столбец внешнего ключа, с помощью быстрого сопоставления NHibernate - PullRequest
0 голосов
/ 03 сентября 2018

Что я пытаюсь сделать
Я моделирую приложение, в котором люди (участники) участвуют в беседе, где у каждого из них есть список тегов, которые определяют их причины для разговора.

Пример
Алиса является участником беседы, и она помечена как автор определенного коммита, а Боб помечен как рецензент этого коммита.

Ограничения

  • Участник имеет коллекцию тегов
  • Нет двунаправленных ассоциаций, поэтому Класс тегов не знает об участниках (Двунаправленные ассоциации сложнее управлять в коде модели домена)
  • Теги должны быть сохранены в отдельной таблице с составным 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" />
...