Transformer un DataTable en Dictionnaire C#

je veux savoir comment transformer un DataTable dans 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 j'obtiens:

Système.Données.EnumerableRowCollection ne contient pas de définition du système ToDictionary et de la meilleure méthode d'extension overload.Linq.Parallèle.Énumérable.ToDictionary (System.Linq.ParallelQuery, System.Func, Système.Collection.Générique.IEqualityComrparer)' a certains invalides argumentsch

Comment puis-je résoudre cette?

Merci

26
demandé sur cadrell0 2013-10-31 21:24:48

6 réponses

La méthode générique ToDictionary a 3 paramètres. Tu en as oublié un, donc il ne sait pas quoi faire. Si vous souhaitez spécifier tous les paramètres, il 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 désactivez, le compilateur est capable de déduire les types, donc vous n'obtenez pas l'erreur.

64
répondu cadrell0 2013-10-31 17:44:06

Tous les previos réponses ne m'a pas aidé, j'ai donc fait ceci:

myList = dt.AsEnumerable()
.ToDictionary<DataRow, string, string>(row => row[0].ToString(),
                                       row => row[1].ToString()); 

et il fonctionnait très bien!

12
répondu ParPar 2014-03-06 09:46:14

ToDictionary attend le IEnumberable<T> comme premier type... vous disiez que c'était une chaîne qui est faux IEnumerable<DataRow>

cela devient confus si vous spécifiez 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));
}
6
répondu Kevin 2013-10-31 17:47:03

je pense que cela va vous aider:

            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));
2
répondu terrybozzio 2013-10-31 17:43:24

j'ai trouvé la solution mais je ne sais pas pourquoi. J'ai modifié ma Question en complétant le code juste pour clarifier ce que je faisais et j'ai changé à ceci

    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;
    }
1
répondu Maximus Decimus 2013-10-31 17:41:01

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 aussi traiter des booléens ou d'autres types de données en appelant la méthode ToString.

notez que ceci retourne une liste de dictionnaires, vous pouvez la modifier en un dictionnaire de dictionnaires si vous avez la clé pour chaque ligne.

itérer sur un bool colonne peut ressembler à de la sorte:

var list = GetDataTableDictionaryList(dt);

foreach (var row in list)
{
    if (row["Selected"].Equals("true", StringComparison.OrdinalIgnoreCase))
    {
        // do something
    }
}
1
répondu Yakir Manor 2018-06-24 13:37:36