I’m trying to cast a List of Dictionary objects to a dataset. The List comes from a JSON parser. I decided to use this as an opportunity to learn about extension methods.
The extension method for a single dictionary works, but the method for a List of Dictionaries doesn’t “look” right to me, mainly because the call becomes
DataSet myExampleDataSet = myExampleDictionary.ToDataSet<Dictionary<string,string>,string,string>();
Am I missing something? Does it really have to be this complicated? Should I just throw the Dictionary .ToDataSet method in a foreach?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Collections;
//fixed code below
namespace TT.Utils
{
public static class DictionaryExtensions
{
/// <summary>
/// Dictionary to DataSet
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="currentDictionary"></param>
/// <returns></returns>
public static DataSet ToDataSet<TKey, TValue>(this IDictionary<TKey, TValue> currentDictionary)
{
DataSet exportedDataSet = new DataSet();
DataTable exportedDataTable = exportedDataSet.Tables.Add();
foreach (TKey key in currentDictionary.Keys)
{
exportedDataTable.Columns.Add(key.ToString());
}
DataRow newRow = exportedDataTable.NewRow();
foreach (KeyValuePair<TKey, TValue> entry in currentDictionary)
{
string key = entry.Key.ToString();
string val = string.Empty;
if (entry.Value != null)
{
val = entry.Value.ToString();
}
newRow[key] = val;
}
exportedDataSet.Tables[0].Rows.Add(newRow);
return exportedDataSet;
}
/// <summary>
/// List of dictionaries to dataset
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="currentList"></param>
/// <returns></returns>
public static DataSet ToDataSet<TKey,TValue>(this IList<Dictionary<TKey,TValue> currentList)
{
DataSet exportedDataSet = new DataSet();
DataTable exportedDataTable = exportedDataSet.Tables.Add();
foreach (Dictionary<TKey, TValue> currentDictionary in currentList.Cast<Dictionary<TKey,TValue>>())
{
foreach (TKey key in currentDictionary.Keys)
{
if (!exportedDataTable.Columns.Contains(key.ToString()))
exportedDataTable.Columns.Add(key.ToString());
}
DataRow newRow = exportedDataTable.NewRow();
foreach (KeyValuePair<TKey, TValue> entry in currentDictionary)
{
string key = entry.Key.ToString();
string val = string.Empty;
if (entry.Value != null)
{
val = entry.Value.ToString();
}
newRow[key] = val;
}
exportedDataSet.Tables[0].Rows.Add(newRow);
}
return exportedDataSet;
}
}
}
You generally don’t need to explicitly define the generic type arguments used when calling a generic method. The types will be implied by the types of the arguments you are calling with. If there’s an ambiguity, the compiler will let you know.
e.g.,
Oops, I didn’t realize you overloaded
ToDataSet(). I only saw the first one which took a singleIDictionary<TKey, TValue>.But either way, the second overload should have the generic parameters the same as the first. It will be a
IListofIDictionarys so it should be in this form:There are only 2 unknown types here,
TKeyandTValueand that will be implied as usual.