GUID 是概率性唯一标识,需慎用:new Guid() 得空值,Guid.NewGuid() 才生成安全随机 ID;ToString 格式影响序列化与日志;EF Core 中须显式配置主键生成;跨平台传输时解析不敏感大小写与连字符,但格式必须合法。

GUID 在 C# 中不是“生成一次就能一劳永逸”的东西——它本质是概率性唯一标识,用错场景或忽略格式、存储、序列化细节,轻则数据不一致,重则跨平台解析失败。
new Guid() 和 Guid.NewGuid() 的区别必须分清
这是最常被混淆的起点。new Guid() 创建的是全零 GUID(00000000-0000-0000-0000-000000000000),等价于 Guid.Empty;而 Guid.NewGuid() 才真正生成随机(v4)GUID。
- 误用
new Guid()当作新 ID,会导致大量记录共享同一个“空 ID”,数据库主键冲突或查询丢失 -
Guid.NewGuid()基于 RNGCryptoServiceProvider(.NET Core 6+ 用 RandomNumberGenerator),满足密码学安全强度,适合身份标识 - 不要手动拼接字符串构造
Guid,比如new Guid("abc...")—— 若格式非法会抛FormatException,且无法校验版本
ToString() 的不同格式影响序列化和日志可读性
Guid 的 ToString() 有至少 5 种内置格式("D"、"N"、"B"、"P"、"X"),选错会导致 JSON/XML 解析失败或日志中难以比对。
-
guid.ToString("D")→"a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8"(默认,带连字符,推荐用于日志和调试) -
guid.ToString("N")→"a1b2c3d4e5f67890g1h2i3j4k5l6m7n8"(纯 32 位十六进制,适合 URL 查询参数或紧凑存储) -
guid.ToString("B")→"{a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8}"(带大括号,SQL Server 的 UNIQUEIDENTIFIER 字面量常用) - JSON 序列化器(如 System.Text.Json)默认输出
"D"格式;若后端要求无连字符,需自定义JsonConverter<guid></guid>
EF Core 中 Guid 作为主键时的陷阱
用 Guid 替代 int 主键看似简单,但 EF Core 默认行为可能违背直觉:它不会自动为 Guid 属性调用 Guid.NewGuid(),除非显式配置。
- 若实体类声明
public Guid Id { get; set; }且未设默认值,EF 插入时传入的是Guid.Empty,导致 SQL Server 报错Cannot insert the value NULL into column 'Id'(即使字段非空) - 正确做法之一:在属性定义时初始化
public Guid Id { get; set; } = Guid.NewGuid(); - 更推荐做法:用 Fluent API 配置值生成
modelBuilder.Entity<myentity>().Property(e => e.Id).HasDefaultValueSql("NEWID()");</myentity>(SQL Server)或.ValueGeneratedOnAdd()+ 自定义生成器 - 注意迁移脚本:若已有数据表,添加
Guid主键列时必须指定default或允许 null,否则迁移失败
跨系统传输 Guid 时大小写和连字符敏感吗?
不敏感——Guid 解析器(Guid.Parse、Guid.TryParse)完全忽略大小写与连字符位置(甚至支持花括号),但前提是字符串符合基本结构。
-
Guid.Parse("A1B2C3D4-E5F6-7890-G1H2-I3J4K5L6M7N8")✅ -
Guid.Parse("{a1b2c3d4e5f67890g1h2i3j4k5l6m7n8}")❌(缺连字符,格式非法) -
Guid.TryParse("a1b2c3d4e5f67890g1h2i3j4k5l6m7n8", out var g)→ 返回 false,因为"N"格式不能带花括号 - 真正危险的是前端 JavaScript 用
crypto.randomUUID()(返回小写无连字符)传给 C# 接口——只要后端用Guid.TryParse就能兼容;但若直接用Guid.Parse且前端多传了空格或换行,就会炸
GUID 的“唯一性”依赖随机熵和实现版本,v4 占主流但 v1(时间戳+MAC)在某些旧系统仍存在;真正容易被忽略的,是把它当“有序 ID”来用——Guid 比较无业务意义,排序性能差,索引碎片高,别在高频查询字段上盲目替换 long。


















