NHibernate SchemaExport:如何生成有意义的唯一密钥名?

NHibernate SchemaExport:如何生成有意义的唯一密钥名?,nhibernate,schemaexport,Nhibernate,Schemaexport,当我将SchemaExport与SQL Server 2005一起使用时,它会生成唯一的密钥名,如: UQ_uuuuu员工uuuu 03317E3D 如何生成一个名称,如:UQ\uuu Employees\uu name? 甚至在SQL Server中 我认为有两种方法可以做你想做的事情 第一个是在映射文件中指定名称。我知道它适用于外键,尽管我还没有尝试使用唯一键 <property name="KeyId" column="KeyId" type="Int" unique="true"

当我将SchemaExport与SQL Server 2005一起使用时,它会生成唯一的密钥名,如:

UQ_uuuuu员工uuuu 03317E3D

如何生成一个名称,如:UQ\uuu Employees\uu name?
甚至在SQL Server中

我认为有两种方法可以做你想做的事情

第一个是在映射文件中指定名称。我知道它适用于外键,尽管我还没有尝试使用唯一键

<property name="KeyId" column="KeyId" type="Int" unique="true" unique-key="MyKeyName"/>
这也是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>

创建表MyTable(
Id唯一标识符不为空,
名称NVARCHAR(10)不为空,
RowVersion INT不为空,
主键(Id)
)
altertabledbo.mytableadd
约束IX_表_1唯一非聚集(名称)
使用(STATISTICS\u NORECOMPUTE=OFF,IGNORE\u DUP\u KEY=OFF,
在[主]上允许行锁定,允许页锁定
或者创建一个实现
NHibernate.Mapping.IAuxiliaryDatabaseObject
的类,该类将创建DDL语句。
查看并向下滚动至

5.6。辅助数据库对象


这就解释了你需要做什么。

目前(仍然)在NHibernate中还没有一种本机实现这一点的方法。我检查了问题跟踪系统,发现一个问题是在2.0中打开的,从未修复过。我已经下载了NHibernate的源代码,很容易就解决了这个问题。构建项目并不是最简单的,但是一旦你得到了它,它就没有那么糟糕了。我想在这里发布代码snippit,但它有点大,因此如果您需要,请告诉我。

完成SchemaExport后,您可以根据PK所在表的名称重命名所有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

几年前在:

上看到过,第一种方法行不通。当前,指定的唯一键值不用于命名约束,仅用于对映射文件中的列进行分组。我会试试“纳明战略”的方法,“纳明战略”的方法也不行。INamingStrategy只关心表名和列名。对此表示抱歉。我将检查是否有其他方法来完成您的目标。在答案中添加了更多信息。为什么不创建一个与原始问题相关联的请求?Diego,我使用的是3.1版,当前版本是3.3版,因此可能会有问题。另外,我对GitHub还不是很熟悉,这是正确的做法吗?很可能与此相关的代码片段自那时以来没有太大变化(或者根本没有变化)。另外,您还可以获得一些关于Github和pull请求的有趣学习:-)或者,您可以在原始版本或开发列表中发布您的代码更改(如果可能,可以使用单元测试)。
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