简体   繁体   中英

How can I omit NULL values when converting DataRow to a Dictionary in C#?

I am using Newtonsoft.JSON to convert Dictionary objects to JSON, the Dictionary objects are coming from a DataTable object, which I convert to Dictionary in order that I might easily serialize the whole table to JSON.

The function that I am using that converts from a DataDictionary looks like this:

private Dictionary<string, Dictionary<string, object>> DataTableToDictionary(DataTable dt, string prefix, string id)
        {
            var cols = dt.Columns.Cast<DataColumn>().Where( c => c.ColumnName != id );
            return dt.Rows.Cast<DataRow>()
                     .ToDictionary(r => prefix+r[id].ToString(),
                                   r => cols.ToDictionary(c => c.ColumnName, c => r[c.ColumnName]));
        }

I'm not all that handy with this Cast<> and lambda @=>@ stuff in this context. What I want to do is omit all values from the Dictionary where the Dictionary is currently storing a key with a Null.

I suppose I can let the above function finish, then go back and delete all Null values from the dictionary, but that seems a dumb way to go.

The data here is a dictionary of dictionaries, something like this...

{
  "KEYTYPE.1": {
    "FIELD1":  "FRED",
    "FIELD2":   null, 

In case where a field is not null, I want the dictionary to contain the value, and in case above where FIELD2 is NULL for a particular row in the DataTable, I want to omit the key/value pair above showing as "FIELD2": null .

I suspect maybe I should be using some more LINQ stuff instead of the following, which works but is wasteful of memory:

private Dictionary<string, object> EraseNulls(Dictionary<string, object> Dict) 
{  
    Dictionary<string, object> SparseDict = new Dictionary<string,object>();
    foreach(var item in Dict.Keys)
    {
        if (Dict[item] != DBNull.Value)
            SparseDict[item] = Dict[item];
    }
    return SparseDict;
}

private Dictionary<string, Dictionary<string, object>> DataTableToSparseDictionary(DataTable dt, string prefix, string id)
{
    IColumns cols = dt.Columns.Cast<DataColumn>().Where(c => c.ColumnName != id);
    return dt.Rows.Cast<DataRow>()
             .ToDictionary(r => prefix + r[id].ToString(),
              r => EraseNulls( cols.ToDictionary(c => c.ColumnName, c => r[c.ColumnName]) ));


}

Why not replace your original function by:

    Dictionary<string, Dictionary<string, object>> DataTableToDictionary(DataTable dt, string prefix, string id)
    {
        var cols = dt.Columns.Cast<DataColumn>().Where(c => c.ColumnName != id);
        return dt.Rows.Cast<DataRow>()
                 .ToDictionary(r => prefix + r[id].ToString(),
                               r => cols.Where(c => !Convert.IsDBNull(r[c.ColumnName])).ToDictionary(c => c.ColumnName, c => r[c.ColumnName]));
    }

You can simply tell Json.NET to ignore null values via JsonSerializerSettings :

var json = JsonConvert.SerializeObject(
                dictionary, 
                new JsonSerializerSettings 
                { 
                    NullValueHandling = NullValueHandling.Ignore 
                });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM