2009-10-27 5 views
10

Je voudrais convertir un DataTable en un IEnumerable<> de Dictionary<string, object>. J'ai essayé la requête LINQ suivante,Comment convertir un DataTable en IEnumerable <Dictionary <string, object >>?

from DataRow row in ds.Tables[0].AsEnumerable() 
let rowDictionary = new Dictionary<string, object>() 
from DataColumn column in row.Table.Columns.Cast<DataColumn>() 
select rowDictionary.Add(column.ColumnName, row[column]).ToArray(); 

mais je reçois l'erreur suivante:

error CS1943: An expression of type 
'System.Collections.Generic.IEnumerable<System.Data.DataColumn>' is not 
allowed in a subsequent from clause in a query expression with source type 
'System.Data.EnumerableRowCollection<AnonymousType#1>'. Type inference 
failed in the call to 'SelectMany'. 

Je sais que je peux brutale-forcer cela avec une boucle, mais il semble que quelque chose que je devrais pouvoir faire dans LINQ. Merci d'avance pour votre aide!

Répondre

10

Je suppose que ce que vous voulez est un dictionnaire pour chaque colonne à la valeur de mise en correspondance de la ligne:

var dt = new DataTable(); 

var columns = dt.Columns.Cast<DataColumn>(); 
dt.AsEnumerable().Select(dataRow => columns.Select(column => 
        new { Column = column.ColumnName, Value = dataRow[column] }) 
       .ToDictionary(data => data.Column, data => data.Value)); 
+0

Cela a fonctionné, mais pourquoi ne pas le travail de syntaxe de requête? – GuyBehindtheGuy

+1

Je n'ai pas eu la même erreur que vous, mais select doit avoir un objet à sélectionner et non une action (à moins que l'action ne renvoie l'objet). Dictionary.Add renvoie * void *, par conséquent, il ne peut pas être un argument select. – Elisha

+0

Pourquoi utiliser 'columns.Select' pour un nouvel objet, puis un' .ToDictionary' sur cet objet, plutôt qu'un appel '.ToDictionary' directement? – palswim

7

Voici une manière que je le fais dans le format Linq

 var registerdataVerify = (from o in dt.AsEnumerable() 
            select new 
            {           
             DataDef =o["shortName"].ToString(), 
             Value = Convert.ToInt32(o["valueDec"]) 
            }).ToDictionary(n => n.DataDef, n => n.Value); 
4

Pourquoi ne pas quelque chose de simple puisque vous avez linq?

var dt = new DataTable(); 
var columnIndex = 0; 
var columnName = "UserID"; 

var Dict = dt.AsEnumerable().ToDictionary(_ 
      row => row(columnName), _ 
      row => row(columnIndex)); 

Il devient encore plus facile si vous travaillez avec des ensembles de données fortement typées:

var dt = new dsData.UsersDataTable(); 

var Dict = dt.ToDictionary(dr => dr.UserName, dr => dr.UserID); 
Questions connexes