SQL Server EF使用Sequence全局自增ID
在使用 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小时前相关文章
- SQL Server用UUID做主键性能问题和解决方案
- 针对 Go 语言开发的 SQL 驱动模拟库
- 数据库SQL Server2014和SQL Server2019的区别和如何选择?
- Blazor ServerPrerendered模式OnInitialized{Async}执行两次
- EF Core在非MVC项目中需要手动释放吗?
- MySQL server has gone away
- Entity Framework Core 连接PostgreSQL
- .NET C# EntityFrameworkCore(EF)连接PostgreSQL数据库
- .NET EF连接MySQL数据库
- 现在开发使用Sql语句还是ORM更多?
- Symfony/Doctrine中的SQL注入
- 在 Windows Server Server/Windows 11 上安装 VirtIO 驱动程序
- SQL生成框架Vanna.ai用法教程
- .NET自然语言转换为SQL的Nl2Sql项目
- 解决PHP开发中的SQL注入攻击问题
- EF报错Win32Exception: 证书链是由不受信任的颁发机构颁发的。
- EF Core 8 (EF8) Contains报错:Microsoft.Data.SqlClient.SqlException (0x80131904): 关键字 'WITH' 附近有语法错误。
- Entity Framework (EF) 数据库迁移命令教程
- SQL语句优化
- Entity Framework Core反向工程DB First基于数据库生成DbContext和实体类