作者有没有计划把JSON库替换为System.Text.Json, 或者有没有变通的办法替换? 返回

SqlSugar 沟通中
10 302

一是现在公司统一用System.Text.Json, 单独引入Newtonsoft.Json不仅冗余而且有时候冲突

二是System.Text.Json的JsonSourceGeneration性能好又对AOT友好

三是微软一些工具都内置依赖System.Text.Json, 比如net8的httpclient等, 避不开


所以想问下作者, 有没有这方面的打算?

热忱回答10

  • Newtonsoft.Json 也只是sqlsugar内部使用。并没有影响到你的功能层面。

    完美支持AOT。

    0 回复
  • 我们使用PG数据库, 在使用JSON字段的时候, 首先JSON对象序列化和反序列化行为受Newtonsoft.Json的Attribute影响, 定义System.Text.Json的Attribute无效.


    主要是 JsonIgnoreAttribute 和 JsonPropertyNameAttribute 等

    0 回复
  • 你说的是JSON字段是吧

    0 回复
  • 看一下自定义类型,将JSON字段换成自定义类型就行了

    0 回复
  • https://www.donet5.com/Home/Doc?typeId=2542

    标题1.2你想用啥就用啥

    0 回复
  • 我们的数据结构定义类似这样:


        public class 批次类型_数据结构
        {
            /// <summary>
            /// SBS/dbTotal/BatchNO
            /// </summary>
            [Newtonsoft.Json.JsonProperty(propertyName: "23bcf03c9e6145e58391c5ef47dcfd33/3db2641914702092f7c7c89c4dfc5e98/4027d179ff3c9bd1f4cd8cf57b0156a6")]
            public int 批次号 { get; init; }
            
            /// <summary>
            /// SBS/dbTotal/PMBSize_Totalkg
            /// </summary>
            [Newtonsoft.Json.JsonProperty(propertyName: "23bcf03c9e6145e58391c5ef47dcfd33/3db2641914702092f7c7c89c4dfc5e98/599992a217040ae79c5763b8211c6871")]
            public float 批次累计 { get; init; }
        }



    数据库中存储的实际数据是这样


    {
        "23bcf03c9e6145e58391c5ef47dcfd33/3db2641914702092f7c7c89c4dfc5e98/4027d179ff3c9bd1f4cd8cf57b0156a6": 103,
        "23bcf03c9e6145e58391c5ef47dcfd33/3db2641914702092f7c7c89c4dfc5e98/599992a217040ae79c5763b8211c6871": 12.62345
    }


    这样的数据结构定义有很多, 而且结构是在业务中配置, 使用SourceGeneration生成的, 结构可变.

    而且 

    "23bcf03c9e6145e58391c5ef47dcfd33/3db2641914702092f7c7c89c4dfc5e98/599992a217040ae79c5763b8211c6871"

    这样的字符串是上游业务传递下来, 我也没法更改, 

    您说的自定义转换器看起来只能在Attribute中传递Type, 没法传参.  如果用自定义转换器, 得为每个数据结构写个转换器吧

    0 回复
  • https://www.donet5.com/Home/Doc?typeId=2542

    标题1.2你想用啥就用啥


    0 回复
  • 用自定义类型可以实现你的需求

    0 回复
  • 我按照文章内容, 写了测试代码, 但是还有点问题, 能不能帮我看一下哪里不对

        /// <summary>
        /// 自定义Json转换器
        /// </summary>
        public class DbColumnJsonConverter : ISugarDataConverter
        {
            public SugarParameter ParameterConverter<T>(object columnValue, int columnIndex) {
                var json = System.Text.Json.JsonSerializer.Serialize(columnValue);
                return new SugarParameter($"{nameof(DbColumnJsonConverter)}_{columnIndex}", json) {
                    CustomDbType = NpgsqlDbType.Json,
                };
            }
            public T QueryConverter<T>(IDataRecord dataRecord, int dataRecordIndex) {
                var val = dataRecord.GetValue(dataRecordIndex);
                if (val is null || val.Equals(DBNull.Value)) {
                    return default;
                }
                return System.Text.Json.JsonSerializer.Deserialize<T>(val.ToString());
            }
        }
        
        
        /// <summary>
        /// 测试表实体定义
        /// </summary>
        public class Test : IDbModel
        {
            [SugarColumn(IsIdentity = true, IsPrimaryKey = true, ColumnDescription = "自动编号")]
            public int Id { get; set; } = 0;
            
            [SugarColumn(IsJson = true, IsNullable = false, DefaultValue = "{}", ColumnDescription = "数据", SqlParameterDbType =typeof(DbColumnJsonConverter))]
            public TestJson TestJson { get; set; } = new TestJson();
        }
        
        
        /// <summary>
        /// 测试Json数据结构
        /// </summary>
        public class TestJson
        {
            [System.Text.Json.Serialization.JsonPropertyName("name")]
            public string Name { get; set; } = "";
            
            [System.Text.Json.Serialization.JsonPropertyName("children")]
            public List<TestJson> Children { get; set; } = [];
        }


    测试写入代码:


    var test = new Test {
        TestJson = new TestJson {
            Name = "TestName",
            Children = [
                new TestJson {
                    Name = "TestName1",
                    Children = [
                        new TestJson { Name = "TestName1-1" },
                        new TestJson { Name = "TestName1-2" },
                    ]
                },
                new TestJson { Name = "TestName2" },
            ]
        }
    };
    int id = dbClient.Insertable(test).ExecuteReturnIdentity();
    Console.WriteLine($"inserted: {id}");


    实际生成的SQL语句如下, 写入json内容多了一层引号


    INSERT INTO "test"  
               ("test_json")
         VALUES
               (@DbColumnJsonConverter_0) returning "id" [@DbColumnJsonConverter_0 = '"{\u0022Name\u0022:\u0022TestName\u0022,\u0022Children\u0022:[{\u0022Name\u0022:\u0022TestName1\u0022,\u0022Children\u0022:[{\u0022Name\u0022:\u0022TestName1-1\u0022,\u0022Children\u0022:[]},{\u0022Name\u0022:\u0022TestName1-2\u0022,\u0022Children\u0022:[]}]},{\u0022Name\u0022:\u0022TestName2\u0022,\u0022Children\u0022:[]}]}"']


    0 回复
  • 我发现了点问题

    当实体类里的字段, IsJson = true 的时候, 

    传入 ParameterConverter 方法的 columnValue 参数值已经是经过序列化的 JSON 文本了, 

    传入的 columnValue 类型就是 string


    目前只能把实体类里的 IsJson = true, 删除, 改为 ColumnDataType = "text"

    这样传入 ParameterConverter 方法的 columnValue 参数值时原本的 TestJson 类型对象


    这样做虽然最终功能实现没问题, 但是会修改表结构,  实际的数据表中, 字段类型会被修改为 text, 而不是 json



        /// <summary>
        /// 自定义Json转换器
        /// </summary>
        public class DbColumnJsonConverter : ISugarDataConverter
        {
            public SugarParameter ParameterConverter<T>(object columnValue, int columnIndex) {
                    // 当实体类里的字段, IsJson = true 的时候
                    // 这里的 columnValue 已经是经过序列化的 JSON 文本了, 传入的 columnValue 类型就是 string
                    // 这就有问题了啊
                    // 目前只能把实体类里的 IsJson = true, 删除, 改为 ColumnDataType = "text"
                    // 虽然功能没问题, 但是实际的数据表中, 字段类型会被修改为 text, 而不是 json
                var json = System.Text.Json.JsonSerializer.Serialize(columnValue);
                return new SugarParameter($"{nameof(DbColumnJsonConverter)}_{columnIndex}", dic) {
                    CustomDbType = NpgsqlDbType.Json,
                };
            }
            public T QueryConverter<T>(IDataRecord dataRecord, int dataRecordIndex) {
                var val = dataRecord.GetValue(dataRecordIndex);
                if (val is null || val.Equals(DBNull.Value)) {
                    return default;
                }
                return System.Text.Json.JsonSerializer.Deserialize<T>(val.ToString());
            }
        }


    0 回复