You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C#中如何在ExecuteReader读取数据及字符串处理中修改小数分隔符(数据库转JSON场景)

我完全理解你的困扰——直接用Replace(",", ".")确实不够规范,而且之前尝试的ToString(new CultureInfo(...))没生效,问题出在你处理的时机不对:你是先把数据库返回的字段直接转成了字符串,这时候已经是带逗号的固定文本了,再调用ToString自然起不到格式化作用。

下面给你两种规范的解决方案,按推荐程度排序:

方案1:使用强类型属性 + Json序列化配置(最推荐)

这种方式从根源上解决问题,强类型不仅更安全,还能统一控制JSON输出格式:

  1. 修改实体类的数值字段为decimal类型
    因为你的这些字段(mnoz_objmnoz_vyd等)是带小数的数值,用decimalstring更合适(避免解析错误,支持精确计算):

    public class ZebraPolozky
    {
        public string doklad { get; set; }
        public string sklad { get; set; }
        public string reg { get; set; }
        public decimal mnoz_obj { get; set; }
        public decimal mnoz_vyd { get; set; }
        public decimal kc_pce { get; set; }
        public string sarze { get; set; }
        public string datspo { get; set; }
        public decimal veb { get; set; }
        public string poc2 { get; set; }
        public string pvp06pk { get; set; }
        public string znacky { get; set; }
        public string stav { get; set; }
    }
    
  2. 读取数据库时直接获取数值类型
    读取时要处理DBNull的情况,避免空引用或转换错误:

    while (reader.Read())
    {
        var zebraPolozka = new ZebraPolozky
        {
            doklad = reader["doklad"].ToString(),
            sklad = reader["sklad"].ToString(),
            reg = reader["reg"].ToString(),
            // 处理数值字段,先判断是否为DBNull,再转为decimal
            mnoz_obj = reader.IsDBNull(reader.GetOrdinal("mnoz_obj")) ? 0 : reader.GetDecimal(reader.GetOrdinal("mnoz_obj")),
            mnoz_vyd = reader.IsDBNull(reader.GetOrdinal("mnoz_vyd")) ? 0 : reader.GetDecimal(reader.GetOrdinal("mnoz_vyd")),
            kc_pce = reader.IsDBNull(reader.GetOrdinal("kc_pce")) ? 0 : reader.GetDecimal(reader.GetOrdinal("kc_pce")),
            sarze = reader["sarze"].ToString(),
            datspo = reader["datspo"].ToString(),
            veb = reader.IsDBNull(reader.GetOrdinal("veb")) ? 0 : reader.GetDecimal(reader.GetOrdinal("veb")),
            poc2 = reader["poc2"].ToString(),
            pvp06pk = reader["pvp06pk"].ToString(),
            znacky = reader["znacky"].ToString(),
            stav = reader["stav"].ToString(),
        };
        zebraPolozky.Add(zebraPolozka);
    }
    
  3. 序列化时指定文化格式
    用Json.NET的JsonSerializerSettings配置使用不变文化(InvariantCulture),这样小数会自动用点作为分隔符:

    var jsonSettings = new JsonSerializerSettings
    {
        Culture = CultureInfo.InvariantCulture,
        Formatting = Formatting.Indented // 可选,让JSON更易读
    };
    var jsonString = JsonConvert.SerializeObject(zebraPolozky, jsonSettings);
    

方案2:保留字符串属性,规范解析后格式化

如果因为业务限制不能修改实体类属性类型,可以在读取时先把数据库数值解析为decimal,再用指定文化转成字符串:

// 以mnoz_obj为例,其他数值字段同理
var mnozObjValue = reader.IsDBNull(reader.GetOrdinal("mnoz_obj")) 
    ? "0.000" // 空值时的默认值
    : reader.GetDecimal(reader.GetOrdinal("mnoz_obj")).ToString(CultureInfo.InvariantCulture);

// 赋值给实体类
mnoz_obj = mnozObjValue,

这种方式的核心是:先从数据库获取原始数值类型,再用目标文化格式化,而不是直接处理已经被默认文化转成字符串的结果。

为什么之前的方法没生效?

你之前调用reader["mnoz_obj"].ToString(new CultureInfo(...))时,reader["mnoz_obj"]返回的要么是:

  • 数据库存储的字符串类型(已经是"24,000"),此时ToString对字符串本身没有格式化作用;
  • 数据库存储的数值类型,但已经被ODBC连接的默认文化自动转成了带逗号的字符串,再调用ToString也无法改变结果。

只有先获取原始数值类型,再用指定文化格式化,才能得到正确的带点分隔符的字符串。

内容的提问来源于stack exchange,提问作者jenik2205

火山引擎 最新活动