反序列化JSON并获取数据类型

时间:2017-07-05 15:02:57

标签: c# sql json.net deserialization json-deserialization

我是C#的乞丐,一直在努力解决这个问题。

  1. 我有一个Json文件。
  2. 我需要对其进行反序列化并将数据插入SQL中。
  3. 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"
            }
        },
    }
    
  4. 到目前为止我的代码:

    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()]();
    
    
    }
    
  5. 详细说明:

    我们的想法是删除数据库中的所有内容,并在每次运行时重新创建所有内容。因此,它将删除/删除表并使用最新数据重新创建相同的表。

    例如对于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参数,所以我不能传递其他任何东西。有什么方法可以恢复那里的原始数据类型吗?

1 个答案:

答案 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);