C#使用protobuf-net将SQL varbinary反序列化为List<double>的实现方法
实现步骤
1. 定义匹配.proto结构的C#数据类
首先要和JS侧用到的.proto结构完全对齐,假设你之前的.proto定义如下:
syntax = "proto3"; message DoubleList { repeated double values = 1; }
对应的C#类用protobuf-net属性标注的写法:
[ProtoContract] public class DoubleList { [ProtoMember(1)] public List<double> Values { get; set; } = new List<double>(); }
注意:ProtoMember的序号必须和.proto里的字段序号完全一致,proto3下repeated数字类型默认使用packed编码,protobuf-net默认兼容该规则,不需要额外配置
2. 对EF Core返回的字节数组反序列化
直接调用protobuf-net的反序列化方法即可,代码示例:
// 你的EF实体类示例,RawData对应数据库varbinary字段 public class YourEntity { public int Id { get; set; } public byte[] RawData { get; set; } } // 业务逻辑示例 using var context = new YourDbContext(); var entity = context.YourEntities.FirstOrDefault(x => x.Id == 你的查询ID); if (entity?.RawData != null && entity.RawData.Length > 0) { using var ms = new MemoryStream(entity.RawData); var result = Serializer.Deserialize<DoubleList>(ms); // result.Values就是你需要的double类型List集合 }
常见坑点排查
- 字段序号匹配:
ProtoMember标注的序号必须和.proto文件中对应字段的序号完全一致,序号错误会导致反序列化无值或者乱码 - 序列化规则对齐:如果用的是proto2语法且手动指定了packed属性,需要显式配置
[ProtoMember(1, IsPacked = 对应布尔值)]和之前JS侧的序列化规则对齐 - 空值判断:反序列化前先判断字节数组是否为null或者长度为0,避免抛出空引用或者IO异常
无外层包装类的极简写法
如果你的字节数组直接存的是packed编码的double序列,没有外层message包裹,可以不用定义包装类,直接用内置方法读取:
using var ms = new MemoryStream(entity.RawData); var doubleList = Serializer.DeserializeItems<double>(ms, PrefixStyle.None, 1).ToList();
内容的提问来源于stack exchange,提问作者codenet2502
相关产品推荐
相关产品推荐

