C产品如何满足特定用户需求?
- 内容介绍
- 文章标签
- 相关推荐
本文共计963个文字,预计阅读时间需要4分钟。
《使用系统随机数生成器实现唯一标识》
在99%的场景下,使用以下代码行即可生成唯一标识:
别把 new Guid() 当成新 ID
这是最常踩的坑:new Guid() 永远返回全零值 "00000000-0000-0000-0000-000000000000",等价于 Guid.Empty;而 Guid.NewGuid() 才真正生成 v4 随机 GUID。
- 误用
new Guid()作主键 → 数据库插入时所有记录共享同一个 ID,轻则主键冲突,重则数据覆盖 - EF Core 中若实体属性声明为
public Guid Id { get; set; }且没初始化,插入时实际传的是Guid.Empty,SQL Server 会报Cannot insert the value NULL into column 'Id'(即使字段非空) - 判断是否未设置,用
guid == Guid.Empty,不要用string.IsNullOrEmpty(guid.ToString())(永远 false)或guid.ToString() == ""(会抛NullReferenceException)
ToString() 格式选错,JSON 和 URL 就会出问题
GUID 默认转字符串是 "D" 格式(带短横线,36 字符),但不同场景要换格式,否则解析失败或浪费空间:
-
guid.ToString("N")→ 纯 32 位十六进制,无分隔符(如"a1b2c3d4e5f67890g1h2i3j4k5l6m7n8"),适合 URL 查询参数或紧凑存储 -
guid.ToString("B")→ 带大括号和短横线(如"{a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8}"),SQL Server 的UNIQUEIDENTIFIER字面量常用 - 别用
guid.ToString().Replace("-", ""):多一次字符串分配,且原始 GUID 若为 null 会崩;也别试ToString("X")——这不是 GUID 支持的格式,直接抛FormatException
从字符串解析 GUID,必须用 Guid.TryParse()
外部输入(比如 API 请求体、数据库查出的字符串)不可信,Guid.Parse() 遇到非法格式直接炸,而 Guid.TryParse() 返回 bool,安全可控:
-
Guid.TryParse("9b1deb4d3b584709850c61e63514d74f", out var g)→ 成功 -
Guid.TryParse("9b1deb4d-3b58-4709-850c-61e63514d74f", out var g)→ 同样成功(支持带/不带横杠、大小写、花括号) - 唯一硬要求:输入只能是 32 或 36 位合法十六进制字符 + 可选分隔符,不能含空格、下划线、中文等
EF Core 中 Guid 作为主键时的陷阱
EF Core 默认不会自动为 Guid 属性调用 Guid.NewGuid(),除非显式配置:
- 错误写法:
public Guid Id { get; set; }→ 插入时传Guid.Empty,触发数据库约束错误 - 可行但不推荐:
public Guid Id { get; set; } = Guid.NewGuid();→ 构造时即生成,但测试或反序列化时可能绕过 - 更推荐:
modelBuilder.Entity<MyEntity>().Property(e => e.Id).HasDefaultValueSql("NEWID()");(SQL Server)或配合.ValueGeneratedOnAdd()+ 自定义生成器 - 注意迁移脚本:若已有表,添加
Guid主键列时必须提供默认值或允许 null,否则迁移失败
最复杂的点其实不在生成,而在「什么时候不该用」:GUID 是概率性唯一标识,不是时间戳+计数器;它不适合做高并发写入的聚集索引主键(会导致页分裂),也不该被手动拼接或哈希截断来“模拟确定性”——真有这种需求,应评估 ULID 或数据库序列方案,而不是在 Guid 上打补丁。
本文共计963个文字,预计阅读时间需要4分钟。
《使用系统随机数生成器实现唯一标识》
在99%的场景下,使用以下代码行即可生成唯一标识:
别把 new Guid() 当成新 ID
这是最常踩的坑:new Guid() 永远返回全零值 "00000000-0000-0000-0000-000000000000",等价于 Guid.Empty;而 Guid.NewGuid() 才真正生成 v4 随机 GUID。
- 误用
new Guid()作主键 → 数据库插入时所有记录共享同一个 ID,轻则主键冲突,重则数据覆盖 - EF Core 中若实体属性声明为
public Guid Id { get; set; }且没初始化,插入时实际传的是Guid.Empty,SQL Server 会报Cannot insert the value NULL into column 'Id'(即使字段非空) - 判断是否未设置,用
guid == Guid.Empty,不要用string.IsNullOrEmpty(guid.ToString())(永远 false)或guid.ToString() == ""(会抛NullReferenceException)
ToString() 格式选错,JSON 和 URL 就会出问题
GUID 默认转字符串是 "D" 格式(带短横线,36 字符),但不同场景要换格式,否则解析失败或浪费空间:
-
guid.ToString("N")→ 纯 32 位十六进制,无分隔符(如"a1b2c3d4e5f67890g1h2i3j4k5l6m7n8"),适合 URL 查询参数或紧凑存储 -
guid.ToString("B")→ 带大括号和短横线(如"{a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8}"),SQL Server 的UNIQUEIDENTIFIER字面量常用 - 别用
guid.ToString().Replace("-", ""):多一次字符串分配,且原始 GUID 若为 null 会崩;也别试ToString("X")——这不是 GUID 支持的格式,直接抛FormatException
从字符串解析 GUID,必须用 Guid.TryParse()
外部输入(比如 API 请求体、数据库查出的字符串)不可信,Guid.Parse() 遇到非法格式直接炸,而 Guid.TryParse() 返回 bool,安全可控:
-
Guid.TryParse("9b1deb4d3b584709850c61e63514d74f", out var g)→ 成功 -
Guid.TryParse("9b1deb4d-3b58-4709-850c-61e63514d74f", out var g)→ 同样成功(支持带/不带横杠、大小写、花括号) - 唯一硬要求:输入只能是 32 或 36 位合法十六进制字符 + 可选分隔符,不能含空格、下划线、中文等
EF Core 中 Guid 作为主键时的陷阱
EF Core 默认不会自动为 Guid 属性调用 Guid.NewGuid(),除非显式配置:
- 错误写法:
public Guid Id { get; set; }→ 插入时传Guid.Empty,触发数据库约束错误 - 可行但不推荐:
public Guid Id { get; set; } = Guid.NewGuid();→ 构造时即生成,但测试或反序列化时可能绕过 - 更推荐:
modelBuilder.Entity<MyEntity>().Property(e => e.Id).HasDefaultValueSql("NEWID()");(SQL Server)或配合.ValueGeneratedOnAdd()+ 自定义生成器 - 注意迁移脚本:若已有表,添加
Guid主键列时必须提供默认值或允许 null,否则迁移失败
最复杂的点其实不在生成,而在「什么时候不该用」:GUID 是概率性唯一标识,不是时间戳+计数器;它不适合做高并发写入的聚集索引主键(会导致页分裂),也不该被手动拼接或哈希截断来“模拟确定性”——真有这种需求,应评估 ULID 或数据库序列方案,而不是在 Guid 上打补丁。

