Свободный NHibernate — составное сопоставление из дочерней таблицы

#nhibernate #fluent-nhibernate #composite-key

#nhibernate #свободный-nhibernate #составной ключ

Вопрос:

Я уверен, что кто-то должен был сделать это раньше — глядя на предыдущие запросы, возможно, это невозможно сделать с помощью Fluent — но здесь идет:

У меня есть следующие сопоставления

Как вы, вероятно, можете заметить, это не сработает, потому что ключи в дочерней таблице не соответствуют родительской таблице, и поэтому ошибка будет заключаться в том, что количество полей в контракте с внешним ключом не совпадает. Однако я не могу изменить базовые таблицы (и связь является допустимой). Есть ли способ обойти это в fluent nhibernate, чтобы я мог каким-то образом игнорировать ожидаемое объединение в обоих составных полях и присоединяться только к тому, которое соответствует (т. е. field_one?) Hibernate ожидает, что первое и второе поля присутствуют в обоих отображениях.

 public ParentMap()
{
    Table("dbo.SOMEPARENT");
    OptimisticLock.None();
    LazyLoad();
    CompositeId()
    .KeyReference(x => x.FieldOne, x => x.Access.CamelCaseField(Prefix.Underscore), "field_one")
    .KeyReference(x => x.FieldTwo, x => x.Access.CamelCaseField(Prefix.Underscore), "field_two");

    HasMany(x => x.ChildData)
            .Access.CamelCaseField(Prefix.Underscore)
            .Cascade.AllDeleteOrphan()
            .KeyColumns.Add("field_one")
            .NotFound.Ignore();
  

}

 public ChildDataMap()
{
Table("dbo.SOMECHILD");
OptimisticLock.None();
LazyLoad();

CompositeId()
    .KeyProperty(x => x.FieldOne, x => x.Access.CamelCaseField(Prefix.Underscore).ColumnName("field_one"))
    .KeyProperty(x => x.FieldTwo, x => x.Access.CamelCaseField(Prefix.Underscore).ColumnName("field_two"))
    .KeyProperty(x => x.FieldThree, x => x.Access.CamelCaseField(Prefix.Underscore).ColumnName("field_three"))
    .KeyProperty(x => x.FieldFour, x => x.Access.CamelCaseField(Prefix.Underscore).ColumnName("field_four"));
Map(x=>x.DontExecTrigger).Column("dont_exec_trigger").Access.CamelCaseField(Prefix.Underscore);
Map(x=>x.DateField).Column("date_field").Access.CamelCaseField(Prefix.Underscore);
Map(x=>x.DataField).Column("data_field").Access.CamelCaseField(Prefix.Underscore);

References(x => x.Parent)
    .Access.CamelCaseField(Prefix.Underscore)
    .Cascade.All()
    .Fetch.Select()
    .Columns("field_one")
    .NotFound.Ignore()
    .Not.LazyLoad();
  

}

Ответ №1:

С чисто точки зрения базы данных, если значение FieldOne дочерней карты данных всегда отображается в ParentMap FieldOne, а FieldOne является уникальным в ParentMap, то существует внешний ключ от первого ко второму. Но также это означает, что FieldOne является ключом-кандидатом (уникальным в) ParentMap.

Вы должны объявить ограничения FK и UNIQUE базы данных. Вы говорите, что не можете изменить таблицу, но если ограничение допустимо, то это не повлияет ни на одного из ее пользователей. Это должно позволить вам объявить, что ChildDataMap FirstOne ссылается на ParentMap FirstOne. Набор из двух столбцов все еще может быть объявлен PK (при условии, что это так). Но если ParentMap FieldTwo также уникален, его также следует объявить УНИКАЛЬНЫМ и, таким образом, он станет доступен как цель FK с одним столбцом.

Возможно, ограничение УНИКАЛЬНОСТИ и / или FK уже объявлены. Возможно, вам следует просто объявить соответствующее уникальное свойство для FirstOne в ParentMap. Ключевые столбцы.Добавление должно полагаться на его наличие и позволять вам объявлять ссылки в ChildDataMap. Но я предполагаю, что именно здесь ваш код недействителен.

Если Hibernate автоматически не присоединяется к одноименным полям, тогда вы могли бы просто не объявлять ссылки и выполнить собственное объединение в одном поле, чтобы получить набор ссылок, в котором, конечно, будет только один элемент.

Неясно, что вы подразумеваете под «вы не можете изменять таблицы» (включает ли это, вы не можете добавить допустимые ограничения?) или «связь является допустимой» (означает ли это, что FieldOne в родительском файле уникален?). Также помогло бы, если бы вы опубликовали весь соответствующий код, а именно задержки в таблице, включая ограничения.

Если вы можете определить новую таблицу, вы можете добавить StricterParentMap с добавленными ограничениями и объявить ParentMap как ее представление. Это не повлияет на его использование другими пользователями и может не считаться «не может измениться».

Комментарии:

1. Увы, слишком поздно для получения бонуса! Какие методы вы смогли использовать?

2. Привет. В итоге я заставил DBS написать мне представление, которое обеспечивало представление данных — я должен прийти к выводу, что NHibernate не допускает такого сценария. Базовая база данных довольно свободна в своих связях, поэтому просмотр казался самым чистым вариантом. Тем не менее, приветствую ответ..