SQL Server 值生成

此页详细介绍了特定于 SQL Server 提供程序的值生成配置和模式。 建议先阅读有关值生成的常规页

IDENTITY 列

按照约定,配置为在添加时生成值的数字列将设置为SQL Server IDENTITY 列

种子和增量

默认情况下,IDENTITY 列从 1(种子)开始,每添加一行增加 1(增量)。 可以配置不同的种子和增量,如下所示:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.BlogId)
        .UseIdentityColumn(seed: 10, increment: 10);
}

将显式值插入 IDENTITY 列中

默认情况下,SQL Server 不允许将显式值插入 IDENTITY 列中。 为此,必须在调用 SaveChanges() 之前手动启用 IDENTITY_INSERT,如下所示:

using (var context = new ExplicitIdentityValuesContext())
{
    context.Blogs.Add(new Blog { BlogId = 100, Url = "http://blog1.somesite.com" });
    context.Blogs.Add(new Blog { BlogId = 101, Url = "http://blog2.somesite.com" });

    context.Database.OpenConnection();
    try
    {
        context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.Blogs ON");
        context.SaveChanges();
        context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT dbo.Blogs OFF");
    }
    finally
    {
        context.Database.CloseConnection();
    }
}

注意

积压工作中有功能请求,用来在 SQL Server 提供程序内自动执行此操作。

序列

作为 IDENTITY 列的替代方法,可以使用标准序列。 这在各种情况下都很有用;例如,你可能希望多个列从单个序列提取其默认值。

SQL Server 允许创建序列并按序列常规页中的详细信息使用它们。 你需要将属性配置为通过 HasDefaultValueSql() 使用序列。

GUID

对于 GUID 主键,提供程序会自动生成最佳顺序值,类似于 SQL Server NEWSEQUENTIALID 函数。 在某些情况下,在客户端上生成值会更高效,即在插入引用该键的依赖项时,不需要额外的数据库往返来获取数据库生成的值。

若要让 EF 为非键属性生成相同的顺序 GUID 值,请按如下所示对其进行配置:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>().Property(b => b.Guid).HasValueGenerator(typeof(SequentialGuidValueGenerator));
}

Rowversions

SQL Server 的 rowversion 数据类型在更新行时会自动更改。 这一特性使得它非常适用于并发令牌,可用于管理多个事务同时更新同一行的情况。

要充分理解并发令牌及其用法,请阅读并发冲突上的专用页。 要将 byte[] 属性映射到 rowversion 列,请按如下所示对其进行配置:

public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    [Timestamp]
    public byte[] Version { get; set; }
}