C#反序列化JSON文件插入SQL表遇CS0029错误求解决
首先解决你碰到的编译错误:
你收到的报错是:
Error CS0029 No se puede convertir implícitamente el tipo 'WebApplication1.Models.RootModel' en 'System.Collections.Generic.List'
原因很明确:你的getJson方法声明返回List<Models.RootModel>,但你的JSON是单个对象,JsonConvert.DeserializeObject<Models.RootModel>(json)返回的是单个RootModel实例,两者类型不匹配,所以编译器报错了。
修正方法很简单,把方法的返回类型改成单个RootModel就行:
public static Models.RootModel getJson() { using (StreamReader r = new StreamReader("c:\\LOG\\20180528\\201805281039.json")) { string json = r.ReadToEnd(); return JsonConvert.DeserializeObject<Models.RootModel>(json); } }
如果以后你的JSON文件可能包含多个对象组成的数组,那可以把反序列化改成JsonConvert.DeserializeObject<List<Models.RootModel>>(json),同时保持方法返回类型为List<Models.RootModel>,但目前你的JSON是单个对象,所以第一种修改更合适。
再回答你第二个疑问:完全不需要必须反序列化才能插入数据库,这里给你几个替代方案:
1. 用JObject直接解析字段
不需要定义完整的模型类,直接解析JSON的各个节点提取值,之后插入数据库:
using (StreamReader r = new StreamReader("c:\\LOG\\20180528\\201805281039.json")) { string json = r.ReadToEnd(); JObject jObj = JObject.Parse(json); // 逐个提取需要的字段 string id = (string)jObj["id"]; string publisherId = (string)jObj["publisherId"]; string providerId = (string)jObj["headers"]["providerId"]; string orderId = (string)jObj["content"]["orderId"]; // ...提取其他需要的字段 // 之后用ADO.NET、Dapper或EF把这些值插入数据库即可 }
2. 直接在SQL中处理JSON(以SQL Server为例)
如果你的数据库支持JSON函数(比如SQL Server 2016及以上版本),可以直接读取JSON文件内容,用OPENJSON解析后插入表:
-- 读取JSON文件内容 DECLARE @Json NVARCHAR(MAX) = (SELECT BulkColumn FROM OPENROWSET(BULK 'c:\LOG\20180528\201805281039.json', SINGLE_CLOB) AS JsonData) -- 解析并插入数据库 INSERT INTO YourTableName (id, publisherId, providerId, orderId, apiName, ...) SELECT JSON_VALUE(@Json, '$.id') AS id, JSON_VALUE(@Json, '$.publisherId') AS publisherId, JSON_VALUE(@Json, '$.headers.providerId') AS providerId, JSON_VALUE(@Json, '$.content.orderId') AS orderId, JSON_VALUE(@Json, '$.content.apiName') AS apiName, -- ...其他需要的字段 FROM OPENJSON(@Json)
3. 使用动态对象(Dynamic)
不需要提前定义模型类,反序列化为动态对象后直接提取值:
using (StreamReader r = new StreamReader("c:\\LOG\\20180528\\201805281039.json")) { string json = r.ReadToEnd(); dynamic jsonObj = JsonConvert.DeserializeObject(json); string id = jsonObj.id; string publisherId = jsonObj.publisherId; string providerId = jsonObj.headers.providerId; string orderId = jsonObj.content.orderId; // ...后续插入逻辑 }
如果你还是倾向于用模型类的方式,修复完编译错误后,就可以拿到RootModel实例,然后用Entity Framework或者Dapper直接把对象插入数据库。比如用Dapper的示例:
var model = getJson(); using (var connection = new SqlConnection("你的数据库连接字符串")) { connection.Open(); var affectedRows = connection.Execute(@" INSERT INTO YourTableName (id, publisherId, notificationType, providerId, orderId, apiName, ...) VALUES (@id, @publisherId, @notificationType, @headers.providerId, @content.orderId, @content.apiName, ...)", model); }
内容的提问来源于stack exchange,提问作者Gabriel Sule

