雷达智富

首页 > 内容 > 程序笔记 > 正文

程序笔记

SQL Server EF使用Sequence全局自增ID

2024-11-16 2

在使用 Entity Framework (EF) 时,如果需要在 SQL Server 中实现一个 全局自增 ID,可以通过以下方法来实现。全局自增 ID 的需求通常是为了在多表之间实现唯一性递增 ID。

实现方式 1:使用 SQL Server 的 Sequence

Sequence 是 SQL Server 提供的一个用于生成连续数字的功能,非常适合全局自增 ID 的需求。以下是步骤:

1. 创建 Sequence

在 SQL Server 中创建一个全局的 Sequence:

CREATE SEQUENCE GlobalSequence
    START WITH 1
    INCREMENT BY 1;

2. 配置 EF 代码以使用 Sequence

在 EF 的模型配置中,可以使用 HasDefaultValueSql 来指定列的默认值,从而使用 Sequence。

示例代码:

using Microsoft.EntityFrameworkCore;

public class MyDbContext : DbContext
{
    public DbSet<MyEntity> MyEntities { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MyEntity>()
            .Property(e => e.Id)
            .HasDefaultValueSql("NEXT VALUE FOR GlobalSequence");
    }
}

public class MyEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

在这里,NEXT VALUE FOR GlobalSequence 是 SQL Server 的语法,用于从全局 Sequence 中获取下一个值。

实现方式 2:通过 EF Core 的 ValueGenerator

EF Core 提供了自定义 ValueGenerator 的功能,允许在应用程序层面生成全局唯一 ID。

1. 创建自定义 ValueGenerator

创建一个生成器类,从 Sequence 中动态获取值:

using Microsoft.EntityFrameworkCore.ValueGeneration;
using System;
using System.Data.SqlClient;

public class GlobalSequenceValueGenerator : ValueGenerator<int>
{
    public override bool GeneratesTemporaryValues => false;

    public override int Next(EntityEntry entry)
    {
        using (var connection = new SqlConnection("YourConnectionString"))
        {
            connection.Open();
            using (var command = new SqlCommand("SELECT NEXT VALUE FOR GlobalSequence", connection))
            {
                return (int)command.ExecuteScalar();
            }
        }
    }
}

2. 配置模型以使用自定义生成器

在 OnModelCreating 中注册自定义生成器:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyEntity>()
        .Property(e => e.Id)
        .HasValueGenerator<GlobalSequenceValueGenerator>();
}

实现方式 3:手动获取 Sequence 值

在保存实体之前,通过查询 Sequence 获取全局 ID 并手动设置。

1. 获取全局 ID

在需要时直接从数据库中获取 Sequence 值:

using (var connection = new SqlConnection("YourConnectionString"))
{
    connection.Open();
    using (var command = new SqlCommand("SELECT NEXT VALUE FOR GlobalSequence", connection))
    {
        var nextId = (int)command.ExecuteScalar();
        myEntity.Id = nextId;
    }
}

2. 保存实体

将生成的 ID 设置到实体的主键上后保存:

dbContext.MyEntities.Add(myEntity);
dbContext.SaveChanges();

实现方式 4:使用 Guid(若适合)

如果全局自增 ID 不是硬性要求,可以考虑使用 Guid 作为全局唯一标识符:

public class MyEntity
{
    [Key]
    public Guid Id { get; set; } = Guid.NewGuid();

    public string Name { get; set; }
}

这种方法虽然不是自增,但可以避免 Sequence 的性能瓶颈,且在分布式系统中更加方便。

优缺点对比

如果需要高效的全局自增 ID,并且主要使用 SQL Server,推荐使用 Sequence。

如果希望将逻辑完全控制在应用层,可以选择自定义 ValueGenerator。

如果项目是分布式或不需要严格的递增,可以考虑使用 Guid。

选择方案时,需根据业务需求和系统架构特点来决定。

更新于:2小时前
赞一波!

文章评论

评论问答