如何正确获取SQL Server中timestamp类型列的十六进制显示值?
解决SQL Server timestamp/rowversion列的十六进制值显示问题
你的代码中VersionNum = (byte[])dr["VersionNum"]的赋值完全正确,没有错误。你看到的{byte[8]}只是C#中byte[]类型默认的ToString()输出,它只会显示数组的类型和长度,不会展示实际的二进制数据内容。
要得到和SQL Server中一致的十六进制格式(比如0x0000000000007DA1),你需要将读取到的byte[]转换为对应的十六进制字符串,以下是两种可行方案:
方案一:在模型中添加计算属性(保留原始byte数组)
如果需要保留原始二进制数据用于并发控制等场景,可以在Message类中新增一个计算属性,专门输出十六进制格式的字符串:
public class Message : BoBase { public int MessageId { get; set; } public string MessageText { get; set; } public int OrderBy { get; set; } public DateTime BeginDate { get; set; } public DateTime EndingDate { get; set; } public bool IsModal { get; set; } public byte[] VersionNum { get; set; } // 计算属性:将byte数组转换为SQL风格的十六进制字符串 public string VersionNumHex { get { if (VersionNum == null || VersionNum.Length == 0) return null; // SQL Server的timestamp是小端存储,反转数组以匹配显示顺序 byte[] reversedBytes = (byte[])VersionNum.Clone(); Array.Reverse(reversedBytes); return "0x" + BitConverter.ToString(reversedBytes).Replace("-", string.Empty); } } }
使用时直接访问VersionNumHex即可得到类似0x0000000000007DA1的字符串。
方案二:读取时直接转换为字符串(模型改为string类型)
如果不需要保留原始二进制数据,可以直接在读取阶段将byte[]转换为十六进制字符串,并修改模型的属性类型:
修改模型:
public class Message : BoBase { // 其他属性保持不变 public string VersionNum { get; set; } }
修改DataReader读取逻辑:
while (dr.Read()) { byte[] versionBytes = (byte[])dr["VersionNum"]; Array.Reverse(versionBytes); // 反转以匹配SQL的显示顺序 string versionHex = "0x" + BitConverter.ToString(versionBytes).Replace("-", ""); messages.Add(new Message { MessageId = Convert.ToInt32(dr["MessageId"]), MessageText = dr["Message"].ToString(), OrderBy = Convert.ToInt32(dr["orderBy"]), IsModal = Convert.ToBoolean(dr["IsModal"]), BeginDate = Convert.ToDateTime(dr["BeginDate"]), EndingDate = Convert.ToDateTime(dr["EndingDate"]), VersionNum = versionHex }); }
补充说明
SQL Server中的timestamp(现在官方推荐使用rowversion名称)本质是8字节的自动递增二进制数据,用于行版本控制。它本身不是字符串,所以读取到byte[]是正确的原始数据格式,转换为十六进制只是为了满足人类可读的展示需求。
内容的提问来源于stack exchange,提问作者Unconquered82
相关产品推荐
相关产品推荐

