dotnetcore / FreeSql

🦄 .NET aot orm, C# orm, VB.NET orm, Mysql orm, Postgresql orm, SqlServer orm, Oracle orm, Sqlite orm, Firebird orm, 达梦 orm, 人大金仓 orm, 神通 orm, 翰高 orm, 南大通用 orm, 虚谷 orm, 国产 orm, Clickhouse orm, QuestDB orm, MsAccess orm.
http://freesql.net
MIT License
3.98k stars 838 forks source link

InsertOrUpdateDict中null值插入成空字符串'' #1785

Open hjkl950217 opened 1 week ago

hjkl950217 commented 1 week ago

问题描述及重现代码:

            IFreeSql freeSql = new FreeSqlBuilder()
                 .UseConnectionString(DataType.MySql, "server=地址")
                 .UseMonitorCommand(
                    cmd => LogHelper.Info($"执行SQL:{cmd.CommandText}"),
                    (cmd, traceLog) => { }
                    )
                 .Build();

            Dictionary<string, object> testDic = new();
            testDic.Add("Id", "1");
            testDic.Add("Name", "test");
            testDic.Add("Time", "01:35:01");
            Dictionary<string, object> testDic2 = new();
            testDic2.Add("Id", "2");
            testDic2.Add("Name", null);
            testDic2.Add("Time", null);

            freeSql.InsertOrUpdateDict(new[] { testDic, testDic2 })
                 .AsTable("test_migrate")
                 .ExecuteAffrows();

这种情况下,在日志中发现,第2个NameTime被处理成'',导致插入数据库为空字符串或0时间。 测试情况:

  1. 1条数据时, null值被正常处理
  2. 2条数据时,第1条数据所有字段都有值,null值处理成字符串
  3. 2条数据,第1条数据有2个字段为null,null值处理成字符串 (示例代码里就是第2个放在最前面)

目前我可以修改为循环,一次只保证数组里只有一个元素,就能正常处理了

数据库版本

Mysql 8.0

安装的Nuget包

FreeSql.Provider.MySql 3.2.821

.net framework/. net core? 及具体版本

.net 6

2881099 commented 1 week ago

批量确实会有这个问题,目前是采用第一条记录的值作为映射类型。

2881099 commented 1 week ago

表面上是弱类型映射,实际内部操作是使用值的类型作为强类型映射的。

hjkl950217 commented 1 week ago

批量确实会有这个问题,目前是采用第一条记录的值作为映射类型。

我以为是第一条的值,但是测试下来,发现把有null的元素放在第一个,同样有这个问题。

hjkl950217 commented 1 week ago

表面上是弱类型映射,实际内部操作是使用值的类型作为强类型映射的。

恩,这个能理解的。批量插入时,如果是每条数据的每个字段都要重新检查下类型,应该就OK了。 目前我就是强行把dic数组循环,调用InsertOrUpdateDict时一次只传递一个,类型就识别正确了。 如果不好改的话,,在方法上说明清楚情况如何,用的人注意下就行

2881099 commented 1 week ago

嗯,提示尽量不要传null值

hjkl950217 commented 1 week ago

用freesql做数据迁移工具,不得不处理null的情况233.

2881099 commented 1 week ago

了解下源码,可以修改内部 _table 映射成 int?/long? 就不用考虑 null 问题了。

hjkl950217 commented 1 week ago

确实,全引用的。 反正数据库那边, '1'这种,插入int类型的字段也是OK的