NHibernate SchemaExport: как сгенерировать осмысленное уникальное имя ключа?

Когда я использую SchemaExport с SQL Server 2005, он генерирует уникальные имена ключей, например:

UQ__Сотрудники__03317E3D

Как я могу сгенерировать имя, например: UQ__Employees__Name? Даже в SQL Server!


person ldp615    schedule 03.09.2010    source источник


Ответы (3)


Я думаю, что есть несколько способов сделать то, что вы пытаетесь сделать.

Первый — указать имя в файле сопоставления. Я знаю, что это работает для внешних ключей, хотя я не пробовал с уникальными ключами.

<property name="KeyId" column="KeyId" type="Int" unique="true" unique-key="MyKeyName"/>

В NHibernate вы можете изменить стратегию именования, создав класс, реализующий NHibernate.Cfg.INamingStrategy, и добавив этот класс при настройке nhibernate.

ISessionFactory sf = new Configuration()  
     .SetNamingStrategy(new YourNamingStrategy())  
     .Configure()  
     .SchemaExport(true, false);

Это также улучшенная стратегия именования, встроенная в nhibernate. Не могу вспомнить, что он выводит с рук, но стоит попробовать

ISessionFactory sf = new Configuration()
    .SetNamingStrategy(ImprovedNamingStrategy.Instance)
    .Configure()
    .SchemaExport(true, false);

РЕДАКТИРОВАТЬ
Есть несколько других возможностей, которые я обнаружил, первая связана с тегом свойства. есть тег столбца, который имеет ряд атрибутов, которые могут быть полезны.

<property name=KeyID>
  <column name="KeyId" unique-key="MyKeyName"/>
</property>

другой немного сложнее. Вы можете добавить что-то вроде этого

<database-object >
   <create>
      create table MyTable(
      Id UNIQUEIDENTIFIER not null,
      Name NVARCHAR(10) not null,
      RowVersion INT not null,

      primary key (Id)
      )

ALTER TABLE dbo.MyTable ADD  
  CONSTRAINT IX_Table_1 UNIQUE NONCLUSTERED(Name) 
  WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
  ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    </create>
    <drop></drop>
</database-object>

Или создайте класс, реализующий NHibernate.Mapping.IAuxiliaryDatabaseObject, который создаст операторы DDL.
Посмотрите в Руководство по NHiberate на nhibernate.info и прокрутите вниз до

5.6. Вспомогательные объекты базы данных

Это объясняет, что вам нужно делать.

person Nathan Fisher    schedule 03.09.2010
comment
Первый способ не может работать. В настоящее время указанное значение уникального ключа не используется для именования ограничения, а только для группировки столбцов в файле сопоставления. Я попробую способ NamingStrategy. - person ldp615; 03.09.2010
comment
И способ NamingStrategy тоже не может работать. NHibernate.Cfg.INamingStrategy заботится только об именах таблиц и столбцов. - person ldp615; 03.09.2010
comment
Сожалею об этом. Я проверю, есть ли другой способ выполнить то, что вам нужно. - person Nathan Fisher; 03.09.2010
comment
Добавил больше информации в ответ. - person Nathan Fisher; 03.09.2010

В настоящее время (все еще) нет способа сделать это изначально в NHibernate. Я прошел через систему отслеживания проблем и нашел проблему, которая была открыта в версии 2.0 и так и не была исправлена. Я пошел дальше и загрузил исходный код для NHibernate и легко смог решить эту проблему. Создание проекта не самое простое, но как только вы его получите, это не так уж и плохо. Я бы разместил фрагмент кода здесь, но он немного велик для этого, поэтому, если вы хотите, дайте мне знать.

person Michael    schedule 08.06.2012
comment
почему бы не создать запрос на вытягивание, связанный с исходной проблемой? - person Diego Mijelshon; 10.06.2012
comment
Диего, я использую версию 3.1, а текущая версия 3.3, так что это может быть проблематично. Кроме того, я еще не очень хорошо знаком с GitHub, будет ли это правильным курсом действий? - person Michael; 12.06.2012
comment
вполне вероятно, что части кода, связанные с этим, не сильно изменились (или вообще не изменились) с тех пор. Кроме того, вы получите удовольствие от изучения Github и запросов на вытягивание :-) В качестве альтернативы вы можете просто опубликовать свои изменения кода (с модульными тестами, если это возможно) в исходном выпуске или в списке разработчиков. - person Diego Mijelshon; 12.06.2012

После выполнения SchemaExport вы можете переименовать все PK на основе имени таблицы, в которой они находятся:

DECLARE @PKname nvarchar(255), @TName nvarchar(255), @TName2 nvarchar(258) DECLARE PKCursor CURSOR FOR SELECT PK.name, T.name AS Tname FROM sys.sysobjects AS PK INNER JOIN sys.sysobjects AS T ON PK.parent_obj = T.id WHERE (PK.xtype = 'PK') OPEN PKCursor FETCH NEXT FROM PKCursor INTO @PKname, @TName WHILE @@FETCH_STATUS = 0 BEGIN SET @TName2 = 'PK_' + @TName PRINT 'table ' + @TName + ' : renaming ' + @PKname + ' in ' + @TName2 Exec sp_rename @PKname, @TName2, 'OBJECT' FETCH NEXT FROM PKCursor INTO @PKname, @TName END CLOSE PKCursor DEALLOCATE PKCursor

Видел это несколько лет назад по адресу: http://www.primordialcode.com/blog/post/nhibernate-give-primary-key-schemaexport-sql-server-sql-express

person Yosoyadri    schedule 11.07.2014