Je veux savoir comment transformer un DataTable en un dictionnaire. J'ai fait quelque chose comme ça.
using System.Linq;
internal Dictionary<string,object> GetDict(DataTable dt)
{
return dt.AsEnumerable()
.ToDictionary<string, object>(row => row.Field<string>(0),
row => row.Field<object>(1));
}
Mais je reçois:
System.Data.EnumerableRowCollection ne contient pas de définition pour 'ToDictionary' et la meilleure surcharge d'extension de méthode 'System.Linq.Parallel.Enumerable.ToDictionary (System.Linq.ParallelQuery, System.Func, System.Collections.Generic.IEqualityComrparerer)' a des arguments invalides
Comment puis-je résoudre ça?
Merci
La méthode générique ToDictionary
a 3 paramètres. Vous en avez laissé un, donc il ne sait pas quoi faire. Si vous souhaitez spécifier tous les paramètres, ce serait <DataRow, string, object>
.
internal Dictionary<string,object> GetDict(DataTable dt)
{
return dt.AsEnumerable()
.ToDictionary<DataRow, string, object>(row => row.Field<string>(0),
row => row.Field<object>(1));
}
Bien sûr, si vous les laissez désactivés, le compilateur est en mesure d'inférer les types, de sorte que vous n'obtenez pas l'erreur.
Toutes les réponses précédentes ne m'ont pas aidé, alors j'ai fait ceci:
myList = dt.AsEnumerable()
.ToDictionary<DataRow, string, string>(row => row[0].ToString(),
row => row[1].ToString());
et cela a très bien fonctionné!
je préfère cette méthode:
public static List<Dictionary<string, string>> GetDataTableDictionaryList(DataTable dt)
{
return dt.AsEnumerable().Select(
row => dt.Columns.Cast<DataColumn>().ToDictionary(
column => column.ColumnName,
column => row[column].ToString()
)).ToList();
}
la raison en est que ce code peut également traiter des booléens ou d'autres types de données en appelant la méthode ToString.
Notez que cela renvoie une liste de dictionnaires, vous pouvez le modifier en un dictionnaire de dictionnaires si vous avez une clé pour chaque ligne.
itérer sur une colonne booléenne pourrait ressembler à ceci:
var list = GetDataTableDictionaryList(dt);
foreach (var row in list)
{
if (row["Selected"].Equals("true", StringComparison.OrdinalIgnoreCase))
{
// do something
}
}
ToDictionary attend le IEnumberable<T>
comme premier type ... vous lui disiez que c'était une chaîne qui ne va pas c'est IEnumerable<DataRow>
Cela devient confus en spécifiant les types ... essayez ceci ...
internal Dictionary<string,object> GetDict(DataTable dt)
{
return dt.AsEnumerable()
.ToDictionary(row => row.Field<string>(0),
row => row.Field<object>(1));
}
je crois que ceci vous aidera:
DataTable dt = new DataTable();
dt.Columns.Add("Column1");
dt.Columns.Add("Column2");
dt.Rows.Add(1, "first");
dt.Rows.Add(2, "second");
var dictionary = dt.Rows.OfType<DataRow>().ToDictionary(d => d.Field<string>(0), v => v.Field<object>(1));
J'ai trouvé la solution mais je ne sais pas pourquoi. J'ai édité ma question en complétant le code juste pour être clair sur ce que je faisais et je l'ai changé
internal Dictionary<string, object> GetDict(DataTable dt)
{
Dictionary<String, Object> dic = dt.AsEnumerable().ToDictionary(row => row.Field<String>(0), row => row.Field<Object>(1));
return dic;
}
Les solutions données supposent seulement 2 colonnes. Si vous souhaitez une représentation multi-colonnes, vous avez besoin d'une liste de dictionnaires
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("Column1");
dt.Columns.Add("Column2");
dt.Columns.Add("Column3");
dt.Rows.Add(1, "first", "A");
dt.Rows.Add(2, "second", "B");
var dictTable = DataTableToDictionaryList(dt);
var rowCount = dictTable.Count;
var colCount = dictTable[0].Count;
//Linq version
var dictTableFromLinq = dt.AsEnumerable().Select(
// ...then iterate through the columns...
row => dt.Columns.Cast<DataColumn>().ToDictionary(
// ...and find the key value pairs for the dictionary
column => column.ColumnName, // Key
column => row[column] as string // Value
)
).ToList();
}
public static List<Dictionary<string, object>> DataTableToDictionaryList(DataTable dt)
{
var result = new List<Dictionary<string, object>>();
//or var result = new List<Dictionary<string, string>>();
foreach (DataRow row in dt.Rows)
{
var dictRow = new Dictionary<string, object>();
foreach (DataColumn col in dt.Columns)
{
dictRow.Add(col.ColumnName, row[col]);
//or dictRow.Add(col.ColumnName, row[col].ToString());
}
result.Add(dictRow);
}
return result;
}
}