#c# #.net #nhibernate
#c# #.net #nhibernate
Вопрос:
При использовании NHibernate, если у меня есть объект, который имеет уникальное ограничение и который может быть однозначно идентифицирован с помощью этого ограничения, лучше ли представлять ограничение как составной ключ или иметь отдельное поле Id и иметь составное уникальное ограничение? Я читал, что использование составных ключей с NHibernate считается «плохим», если это может помочь, и должно использоваться только при работе с устаревшими базами данных.
Представьте настройку следующим образом:
class Book
{
public virtual int Id { get; protected set; }
public virtual string Author { get; set; }
public virtual IList<BookEdition> Editions { get; set; } //HasMany (one to many)
}
class BookEdition
{
public virtual string Title { get; set; }
public virtual string Language { get; set; }
public virtual int Edition { get; set; }
}
Здесь у нас есть ограничение для BookEdition, где оно имеет ограничение на язык и издание, т. е. не может быть двух изданий книги на одном языке. Любая редакция также может быть однозначно идентифицирована по номеру редакции и языку.
Какой подход считается лучшим в NHibernate? Использовать язык / издание в качестве составного идентификатора или ввести переменную Id для BookEdition и вместо этого иметь составное уникальное ограничение?
Ответ №1:
Заменяющий ключ (дополнительная переменная Id) лучше в целом, а не только в NHibernate. Проблема с естественными ключами (здесь: Язык и редакция) заключается в том, что они имеют «деловое» значение. Потребности бизнеса развиваются со временем, и вам, безусловно, придется менять свои естественные ключи в будущем, что может быть очень болезненным. Кроме того, ваши SQL-соединения и условия where будут более сложными.
Это может быть FNH-сопоставление BookEdition с составным уникальным ограничением:
Id(x => x.Id);
Map(x => x.Title);
Map(x => x.Language).UniqueKey("MyCompositeUniqueConstraint");
Map(x => x.Edition).UniqueKey("MyCompositeUniqueConstraint");
Кстати. рекомендуется не показывать значения ключа surrorgate клиентам. Они склонны придавать им какое-то деловое значение, а затем также хотят их изменить :).
Комментарии:
1. Это было сопоставление, о котором я тоже думал. Хорошая ли идея переопределить Equals / GetHashCode также для использования естественного ключа? В моем базовом классе у меня есть оператор Equals, который работает со свойством Id, но это неточно для данного случая. Я думаю, также невозможно иметь составной естественный ключ, используя «NaturalID()». Я также не очень понимаю разницу между естественным идентификатором и уникальным ограничением в терминах гибернации..
2. Уникальное ограничение IMO (или ключ) не играет никакой роли во внутренностях NH. Это всего лишь руководство по созданию db. schema (создание ограничения для таблицы). С другой стороны, первичный ключ (составной, естественный, окружающий — не имеет значения) является фундаментальной концепцией для ИЛИ отображения. В нем говорится, как однозначно найти объект в таблице базы данных.
3. Хм, кажется, что всегда полезно переопределять Equals и, следовательно, GetHashCode, особенно когда задействованы отложенная загрузка и прокси ( devlicio.us/blogs/billy_mccafferty/archive/2007/04/25 /… ). Очень интересно, спасибо за ваш вопрос, похоже, я пока ничего не знаю о NH :).