EF Core对Guid主键默认采用客户端生成策略,即调用Add()时由.NET生成Guid.NewGuid();也可配置数据库端生成(如SQL Server的NEWID())或手动控制(DatabaseGeneratedOption.None);但需避免将Guid直接设为聚集索引以防止索引碎片。
EF Core 对 Guid 主键有原生支持,默认就会按客户端生成方式处理,不需要额外配置就能用,但要真正用好,得清楚几种生成策略的区别和适用场景。
只要实体类主键属性是 Guid 类型、名字叫 Id 或 实体名+Id(比如 UserId),EF Core 就会自动把它识别为主键,并启用 ValueGeneratedOnAdd() —— 也就是在调用 Add() 时,由 .NET 客户端生成 Guid.NewGuid(),再插入数据库。
如果希望数据库负责生成 Guid(比如用 SQL Server 的 NEWID() 或 NEWSEQUENTIALID()),就得在 OnModelCreating 中显式配置:
.HasDefaultValueSql("NEWID()")(随机)或 "NEWSEQUENTIALID()"(顺序,减少索引碎片).HasDefaultValueSql("gen_random_uuid()")(需启用 pgcrypto 扩展).HasDefaultValueSql("uuid()")
.ValueGeneratedOnAdd(),否则 EF 不会跳过赋值如果你要在代码里完全自己控制 Guid 值(比如从外部系统传入、或复用旧数据),就用这个方式:
[DatabaseGenerated(DatabaseGeneratedOption.None)]
.ValueGeneratedNever()
Add() 前必须显式赋值 Id = ...,否则会存 00000000-... 导致重复或约束失败Guid 是 16 字节、无序的,直接设为主键 + 聚集索引会导致严重索引碎片,尤其在高写入场景下:
NEWID() + 聚集主键;可用 NEWSEQUENTIALID() 缓解,但仍建议非聚集主键 + 单独添加自增列作聚集索引id BIGINT AUTO_INCREMENT PRIMARY KEY 作聚集索引,Guid 字段单独建唯一非聚集索引基本上就
