Convert datatable to JSON in C#

后端 未结 17 1315
猫巷女王i
猫巷女王i 2020-11-22 11:53
  1. I want to get records from database into a DataTable.
  2. Then convert the DataTable into a JSON object.
  3. Return the JSON ob
17条回答
  •  野趣味
    野趣味 (楼主)
    2020-11-22 12:42

    All of these answers are really great for moving data! Where they fail is preserving the column type of data being moved. This becomes a problem when you want to do things like merge datatables that appear to be the same. JsonConvert will look at the first row of data to determine the column datatype, which may be guessed incorrectly.

    To get around this;

    • Serialize the DataTable and DataColumn definitions in separate response objects.
    • Deserialize the DataColumn definitions in the response before reading in the table.
    • Deserialize and merge the DataTable ignoring the schema defined by Json.

    It sounds like a lot, but its only three additional lines of code.

    // Get our Column definitions and serialize them using an anoymous function.
    var columns = dt.Columns.Cast().Select(c => new { DataPropertyName = c.ColumnName, DataPropertyType = c.DataType.ToString()});
    resp.ObjSchema = JsonConvert.SerializeObject(columns);
    resp.Obj = JsonConvert.SerializeObject(dt);
    

    resp.ObjSchema becomes;

    [
      {
        "DataPropertyName": "RowId",
        "DataPropertyType ": "System.Int32"
      },
      {
        "DataPropertyName": "ItemName",
        "DataPropertyType ": "System.String"
      }
    ]
    

    Instead of letting Json define the column definitions via dt = JsonConvert.DeserializeObject(response) we can use LINQ on our resp.ObjSchema to define them ourselves. We'll use MissingSchemaAction.Ignore to ignore the schema provided by Json.

    // If your environment does not support dynamic you'll need to create a class for with DataPropertyName and DataPropertyType.
    JsonConvert.DeserializeObject>(response.ObjSchema).ForEach(prop =>
    {
        dt.Columns.Add(new DataColumn() { ColumnName = prop.DataPropertyName, DataType = Type.GetType(prop.DataPropertyType.ToString()) });
    });
    // Merge the results ignoring the JSON schema.
    dt.Merge(JsonConvert.DeserializeObject(response.Obj), true, MissingSchemaAction.Ignore);
    

提交回复
热议问题