为 NHibernate 中的主键列生成顺序 ID

Generate sequential Id for primary key column in NHibernate

如何为 NHibernate 中的主键列生成顺序 guid。我知道如何做那些自动递增的东西。但我不知道如何为主键创建顺序 Guid。

在数据库中,Id列的数据类型是uniqueidentifier。我检查了官方文档和其他一些网络搜索结果。但我找不到任何解决方案。这是我现在拥有的:

public UserMap()
{
    Table("Users");
    Id(x => x.Id);
    Property(x => x.Username, x => x.NotNullable(true));
    Property(x => x.Email, x => x.NotNullable(true));
    Property(x => x.PasswordHash, x =>
    {
        x.NotNullable(true);
        x.Column("password_hash");
    });
}

查看 Adam Bar 的文档

Mapping-by-Code - Id, NaturalId

让我引用:

The most common primary key mapping is available through Id method.

Id(x => x.Id, m =>
{
    m.Column("id");

    m.Generator(Generators.Native, g => g.Params(new
    {
        // generator-specific options
    }));

    m.Length(10);
    m.Type(new Int32Type());
    m.Access(Accessor.Field);
});

There are several features missing - like unsaved-value (will be added in NHibernate 3.3) or DDL column options.

Probably the most important option is Generator. It specifies the way NHibernate (or database) generates unique values. There are 8 predefined types of generators available through static Generators class:

public static class Generators
{
    ...

    // Guid
    public static IGeneratorDef Guid { get; }

    // sequential Guid
    public static IGeneratorDef GuidComb { get; }

因此,基于此,我们可以像这样调整映射:

public UserMap()
{
    Table("Users");
    Id(x => x.Id, m =>
    {
        m.Generator(Generators.GuidComb);
    }
    ...

我是这样做的:

在我的企业实体中类

public abstract class EntityBase : IEntity
{
    public virtual Guid Id { get; protected set; }
    ...
}

流畅的映射:

Id(x => x.Id).GeneratedBy.GuidComb();

阅读 this 关于 Guid.comb

如果您使用的是 SQL Server 2012 或更新版本,您可以创建序列并将其用于 IdGeneration。例如:

mapping.Id(x => x.Id).GeneratedBy.Sequence("TableSequence");

要使其正常工作,您必须确保在 hibernate-configuration 中将 属性 设置为: <property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property> 或更高版本。

要创建序列,您可以使用如下迁移脚本:

DECLARE @Command NVARCHAR(255);
DECLARE @SequenceStartId INT;

/* Create TableSequence */
IF EXISTS (SELECT * FROM sys.sequences WHERE OBJECT_ID = OBJECT_ID('dbo.TableSequence'))
BEGIN
   DROP SEQUENCE dbo.[TableSequence]
END

SET @SequenceStartId = (SELECT MAX(Id) FROM dbo.[Table]) + 1;

SET @Command = FORMATMESSAGE('
      CREATE SEQUENCE dbo.TableSequence
      START WITH %i  
      INCREMENT BY 1 AS INT;
   ', @SequenceStartId)

EXECUTE sp_executesql @Command

关于序列的更多信息: https://docs.microsoft.com/en-us/sql/t-sql/statements/create-sequence-transact-sql?view=sql-server-ver15