我是C#的乞丐,一直在努力解决这个问题。
Json文件看起来像这样:
{
"records": [
{
"class": "Abc",
"id": "7720170378514849999",
"fields": {
"name": "xyz",
"created_at": "2015-02-26 15:06:48 UTC",
"updated_at": "2017-05-08 15:31:45 UTC",
"domain": "domainname",
"month": null,
"secure": true,
"filters": null,
"users_counter": 373
},
"links": {
}
},
{
"class": "User",
"id": "7765907511856219999",
"fields": {
"first_name": "aaa",
"last_name": "bbb",
"email": "aaa@domain.com",
"timezone": null,
"local": null,
"unsubscribe": false,
"address_verified": false
},
"links": {
"Abc_id": "7720170378514849999"
}
},
}
到目前为止我的代码:
public void doConvert()
{
string unzippedFileName = "c:\\tar\\finish\\UnzippedFile.json";
List<dynamic> allEntities = new List<dynamic>();
try
{
var deserialisedJson = JsonConvert.DeserializeObject<dynamic>
(System.IO.File.ReadAllText(@unzippedFileName));
var records = deserialisedJson.records;
foreach (var item in records)
{
string itemString = item.ToString();
var deserialisedItem =
JsonConvert.DeserializeObject<Dictionary<dynamic, dynamic>>
(itemString);
var className = deserialisedItem["class"];
var classId = deserialisedItem["id"];
dynamic classFields = deserialisedItem["fields"];
var deserialisedClassFields =
JsonConvert.DeserializeObject<Dictionary<dynamic, dynamic>>
(classFields.ToString());
dynamic classLinks = deserialisedItem["links"];
var deserialisedClassLinks = JsonConvert.DeserializeObject<Dictionary<dynamic, dynamic>>(classLinks.ToString());
ParseIntoType(className);
ParseIntoType(classId);
foreach (KeyValuePair<dynamic, dynamic> entry in deserialisedClassFields)
{
ParseIntoType(entry.Key);
}
foreach (KeyValuePair<dynamic, dynamic> entry in deserialisedClassLinks)
{
ParseIntoType(entry.Key);
}
buildsqlstatements() // My issue is here
}
}
catch (Exception ee)
{
Log.ErrorFormat("Exception:{0}", ee.ToString());
}
}
public void ParseIntoType(dynamic itemTobeParsed)
{
new Dictionary<Type, Action>{
{typeof(bool), () => boolEntityList.Add(itemTobeParsed)},
{typeof(int), () => intEntityList.Add(itemTobeParsed)},
{typeof(BigInteger), () => bigIntEntityList.Add(itemTobeParsed)},
{typeof(double), () => doubleEntityList.Add(itemTobeParsed)},
{typeof(DateTime), () => dateTimeEntityList.Add(itemTobeParsed)},
{typeof(string), () => stringEntityList.Add(itemTobeParsed)},
{typeof(TextReader), () => textEntityList.Add(itemTobeParsed)},
}[itemTobeParsed.GetType()]();
}
详细说明:
我们的想法是删除数据库中的所有内容,并在每次运行时重新创建所有内容。因此,它将删除/删除表并使用最新数据重新创建相同的表。
例如对于Users表,我将首先删除任何(从昨天运行)Users_temp表,然后创建Users_temp表,将最新数据插入此表,然后删除Users表,然后将Users_temp重命名为Users表。我的问题是,为了创建Users_temp表,我必须定义它的列类型。所以我必须获取first_name的数据类型,它将以字符串形式出现,然后我将以某种方式将其映射到varchar(255),然后构建sql语句。
创建表用户( first_name varchar(255) lastname varchar(255) 时区日期时间 );
//string createTmpTable = "create table "+className+" ((column = deserialised key from fields, datatype = its datatype))";
现在发生的事情是将所有内容解析为字符串。甚至时区或任何int数据也会被解析为字符串。所以我无法构建sql语句,因为我没有获得正确的数据类型。我假设这是因为这些行:
foreach (var item in records)
{
string itemString = item.ToString();
var deserialisedItem =
JsonConvert.DeserializeObject<Dictionary<dynamic, dynamic>>(itemString);
因为我正在将项目转换为itemString,所以一切都变成了一个字符串。 JsonConvert.DeserializeObject只接受String参数,所以我不能传递其他任何东西。有什么方法可以恢复那里的原始数据类型吗?
答案 0 :(得分:0)
如果无法在json字符串中找到它们,您可以使用类型化模型并告诉JsonConvert将字段保留为null。您可以利用它并在类型化的模型结构中提供所有可能的字段。您可以获得验证数据在进入数据库之前是否正确输入的好处。
public class Record
{
public string @class {get; set;}
public string id { get; set; }
public List<RecordField> fields { get; set; }
public Dictionary<string,string> links { get; set; }
}
public class RecordField
{
// fields from first object in the array
public string name { get; set; }
public DateTime created_at { get; set; }
public DateTime updated_at { get; set; }
public string domain { get; set; }
public int month { get; set; }
public bool secure { get; set; }
public List<string> filters { get; set; }
public int user_count { get; set; }
// fields from second object in the array
public int first_name { get; set; }
//...
}
要让JsonConvert知道可能缺少的字段,您需要在转换前设置以下设置:
var settings =
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
var records = JsonConvert.DeserializeObject<List<Record>>(json, settings);