【问题标题】:NHibernate SchemaExport: How to generate a meaningful unique key name?NHibernate SchemaExport:如何生成有意义的唯一键名?
【发布时间】:2011-04-07 15:19:36
【问题描述】:

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

UQ__Employees__03317E3D

我怎样才能生成一个名字,比如:UQ__Employees__Name? 即使在 SQL Server 中!

【问题讨论】:

    标签: nhibernate schemaexport


    【解决方案1】:

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

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

    <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 manual on nhibernate.info 并向下滚动到

    5.6。辅助数据库对象

    这说明了您需要做什么。

    【讨论】:

    • 第一种方式行不通。目前,唯一键的指定值不用于命名约束,仅用于对映射文件中的列进行分组。我会尝试“命名策略”的方式。
    • 而且“命名策略”的方式也行不通。 NHibernate.Cfg.INamingStrategy 只关心表名和列名。
    • 对此感到抱歉。我会检查是否有其他方法可以完成您的目标。
    • 在答案中添加了更多信息。
    【解决方案2】:

    目前(仍然)没有一种方法可以在 NHibernate 中本地执行此操作。我浏览了问题跟踪系统,发现了一个在 2.0 中打开但从未修复的问题。我已经下载了 NHibernate 的源代码,并且很容易解决这个问题。构建项目并不是最简单的,但一旦你得到它,它并没有那么糟糕。我会在这里发布代码片段,但它有点大,所以如果你想要它,请告诉我。

    【讨论】:

    • 为什么不创建与原始问题相关的拉取请求?
    • Diego,我使用的是 3.1 版本,而当前版本是 3.3,所以可能会有问题。另外,我对 GitHub 还不是很熟悉,这会是正确的做法吗?
    • 从那时起,与此相关的代码片段可能并没有太大(或根本没有)改变。另外,您可以在学习 Github 和拉取请求方面获得一些乐趣 :-) 或者,您可以在原始问题或开发列表中发布您的代码更改(如果可能,使用单元测试)。
    【解决方案3】:

    执行 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看到它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多