MySqlDataReader.GetGuid返回错误UUID的技术问询
问题原因
你用UUID_TO_BIN(UUID(), true)存储UUID时,MySQL会将UUID字符串的前3个分组(8-4-4字节)从大端字节序转为小端字节序后存入BINARY(16),目的是提升索引性能。但MySql.Data 8.3.0的GetGuid方法,即使设置OldGuids=true,也无法正确匹配这种swap后的字节序规则,导致读取的Guid和数据库查询结果不一致。
OldGuids=true是为兼容旧版MySQL(5.x及之前)的UUID存储格式设计的,和UUID_TO_BIN(..., true)的swap逻辑不匹配,所以设置后无效。
解决办法
有三种可行方案,按需选择:
方案1:存储时不使用swap_flag
将存储语句改为UUID_TO_BIN(UUID()),这样存储的二进制字节序和.NET Guid的原生存储格式完全一致,直接用GetGuid就能获取正确的UUID:
INSERT INTO your_table (col) VALUES (UUID_TO_BIN(UUID()));
C#代码无需修改,缺点是UUID作为主键的索引性能会略低于swap后的存储方式。
方案2:手动调整字节序读取
读取数据库的二进制数组,手动调整前3个分组的字节序后构造Guid,保留swap存储的索引优势:
// 读取二进制数组 byte[] rawBytes = dataReader.GetFieldValue<byte[]>("col"); // 调整字节序匹配UUID_TO_BIN(..., true)的swap规则 byte[] adjustedBytes = new byte[16]; // 处理第一个8字符分组(原大端转小端存储,现在转回来) adjustedBytes[0] = rawBytes[3]; adjustedBytes[1] = rawBytes[2]; adjustedBytes[2] = rawBytes[1]; adjustedBytes[3] = rawBytes[0]; // 处理第二个4字符分组 adjustedBytes[4] = rawBytes[5]; adjustedBytes[5] = rawBytes[4]; // 处理第三个4字符分组 adjustedBytes[6] = rawBytes[7]; adjustedBytes[7] = rawBytes[6]; // 后8字节无需调整,直接复制 Array.Copy(rawBytes, 8, adjustedBytes, 8, 8); // 构造正确的Guid Guid correctUuid = new Guid(adjustedBytes); Console.WriteLine(correctUuid.ToString());
方案3:查询时直接获取UUID字符串
在SQL查询中用BIN_TO_UUID(col)直接返回UUID字符串,再用Guid.Parse转换,代码最简单:
SELECT BIN_TO_UUID(col) AS col FROM your_table;
C#代码:
string uuidStr = dataReader.GetString("col"); Guid correctUuid = Guid.Parse(uuidStr); Console.WriteLine(correctUuid.ToString());
内容的提问来源于stack exchange,提问作者Karmeye
相关产品推荐
相关产品推荐

