//数据初始化 Dictionary<string, ClassInfo> aa = new Dictionary<string, ClassInfo>();
ClassInfo c1 = new ClassInfo() {Name = "班级1", Cnt = 42}; ClassInfo c2 = new ClassInfo() {Name = "班级2", Cnt = 45}; aa.Add("001", c1); aa.Add("002", c2);//序列化 string bb = JsonConvert.SerializeObject(aa);//反序列化 var cc = JsonConvert.DeserializeObject<Dictionary<string, ClassInfo>>(bb);internal class Person { public string Name { get; set; } public int Age { get; set; } public string[] Mobiles { get; set; } }
先解析SQL转成dataset。再用SqlBulkCopy批量插入
是不是还是要逐条解析json,逐条数据写入dataset,再将dataset整个传到数据库?
所谓“方便”,没有绝对的方便,你可能觉得“不写代码才最方便”。但是既然已经写完毕了,那么你何必要修改呢?整天纠结已经写完毕、运行得很好的代码,才是最“不方便”的行为。如果是从“容易调试修改”的角度,那么使用强类型的.net业务实体对象(而不是JObjec、JArray)这可以保证代码比较清晰、易诊断问题。这就不是简单地图方便,而是考虑到修改维护的真正方便。至于说“速度慢”,我不知道有多慢?!这或许只是个借口吧。我不知道你是不是觉得写一条sql语句就不“方便了”。如果你不直接写sql语句然后在循环中重复使用,而是弄个什么datatable之类的,那可能是自找麻烦的。
ResultType jo = JsonConvert.DeserializeObject<DeserializeObject>(ret);这样的强类型的实体数据结构。如果你纠结于“速度慢、不方便”,那么就保持你的代码就行了。只要是弱类型、随意解释凌乱的数据的代码,不管怎么写都一样。
所谓“方便”,没有绝对的方便,你可能觉得“不写代码才最方便”。但是既然已经写完毕了,那么你何必要修改呢?整天纠结已经写完毕、运行得很好的代码,才是最“不方便”的行为。如果是从“容易调试修改”的角度,那么使用强类型的.net业务实体对象(而不是JObjec、JArray)这可以保证代码比较清晰、易诊断问题。这就不是简单地图方便,而是考虑到修改维护的真正方便。至于说“速度慢”,我不知道有多慢?!这或许只是个借口吧。我不知道你是不是觉得写一条sql语句就不“方便了”。如果你不直接写sql语句然后在循环中重复使用,而是弄个什么datatable之类的,那可能是自找麻烦的。我现在追求速度,容易调试和修改在其次。我要对接N多微商城,现在对接了十几个,每次同步的数据2万条左右,用我帖子里的做法,每次同步的时间3分钟左右。如果对接的店铺越来越多,这个速度就太慢了。
你是否测试过,是把时间主要花在从 JArray 中读取数据或者是写个 Insert 或者 Update 语句上吗?
你是否测试过,是把时间主要花在从 JArray 中读取数据或者是写个 Insert 或者 Update 语句上吗?往数据库写数据花了90%以上的时间。
你是否测试过,是把时间主要花在从 JArray 中读取数据或者是写个 Insert 或者 Update 语句上吗?往数据库写数据花了90%以上的时间。解析一条就插一条,数据库又是open又是close的,当然慢了~~
解析这个步骤,肯定花费不了多少时间的,因为json本身就比xml要轻量,传输的数据量小很多。而且json是格式化的,容易解析。
瓶颈在IO而不是运算。
可以考虑解析到Array/List,然后定义数据库事务操作,通过事务进行批量更新。
或者弄到一个强类型dataset中,使用自动生成的代码和方法进行更新(目测原理也是一条记录就一开一关的,所以要稍作修改,在更新前先手动open,更新完毕后再close,这样会跳过一开一关)。
json转换为DataTable操作方法,再将datatable更新到数据库中,
1.根据数据拼接sql,与数据库只交互一次
2.将json想办法转成datatable,用SqlBulkCopy (oracle用OracleBulkCopy,OracleBulkCopy不支持事务)
具体代码如下
SqlTransaction sqlTran = sqlConn.BeginTransaction();
SqlBulkCopy sbc = new SqlBulkCopy(sqlConn, SqlBulkCopyOptions.Default, sqlTran);
sbc.BulkCopyTimeout = 3600;
sbc.BatchSize = 50000; //一次更新的行数
foreach (DataColumn col in dtLog.Columns)
{
sbc.ColumnMappings.Add(col.ColumnName, col.ColumnName);
}
sbc.DestinationTableName = "\"" + this.SysParameter.DataBaseNodeCode + "\".tbDataCheckLog";
sbc.WriteToServer(dtLog);
这样子,反序列化知道就得到可以写入数据库所需的实体了(假设你的实体和数据库字段一致,否则还是要转成数据库表对应实体)。
Dictionary<string, ClassInfo> aa = new Dictionary<string, ClassInfo>();
ClassInfo c1 = new ClassInfo() {Name = "班级1", Cnt = 42};
ClassInfo c2 = new ClassInfo() {Name = "班级2", Cnt = 45}; aa.Add("001", c1);
aa.Add("002", c2);//序列化
string bb = JsonConvert.SerializeObject(aa);//反序列化
var cc = JsonConvert.DeserializeObject<Dictionary<string, ClassInfo>>(bb);internal class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string[] Mobiles { get; set; }
}