2010-01-05 9 views
4

J'ai un List<string> et j'ai un DataTable.Comparer DataRow collection à la liste <T>

L'une des colonnes d'un DataRow est ID. La liste contient des instances de cet ID.

Le DataTable est renseigné sur une minuterie.

Je souhaite renvoyer des éléments de la liste qui ne sont pas dans le DataTable dans une autre liste.

Répondre

12

Vous voulez faire quelque chose comme ça

var tableIds = table.Rows.Cast<DataRow>().Select(row => row["ID"].ToString()); 

var listIds = new List<string> {"1", "2", "3"}; 

return listIds.Except(tableIds).ToList(); 

Vous pouvez lancer les lignes de la table de données à une collection IEnumerable puis sélectionnez la valeur de la colonne « ID » de chacun d'eux. Vous pouvez ensuite utiliser la méthode d'extension Enumerable.Except pour obtenir toutes les valeurs de la liste qui ne figurent pas dans la collection que vous venez de créer.

Si vous souhaitez obtenir les valeurs figurant dans la table mais pas dans la liste, inversez simplement listIds et tableIds.

+0

+1 pour la coulée de datarow. – mehul9595

+0

+1 .Cast était mon lien manquant à toutes ces merveilleuses méthodes d'extension. – Alain

1

Si votre table était quelque chose comme ça:

DataTable dt = new DataTable(); 
dt.Columns.Add("ID"); 
DataRow dr = dt.NewRow(); 
dt.PrimaryKey = new DataColumn[] {dt.Columns[0]}; 
dr["ID"] = "1"; 
dt.Rows.Add(dr); 
dr = dt.NewRow(); 
dr["ID"] = "2"; 
dt.Rows.Add(dr); 
dr = dt.NewRow(); 
dr["ID"] = "3"; 
dt.Rows.Add(dr); 

et la liste était quelque chose comme ceci:

List<string> ls = new List<string>{"1","2","4"}; 

nous pourrions obtenir les objets trouvés dans la liste et non dans le datatable cette façon :

var v = from r in ls 
       where !dt.Rows.Contains(r) 
       select r; 
     v.ToList(); 
1

Avec une efficacité raisonnable via HashSet<T> (et notant que le f astest façon d'obtenir des données d'un DataRow est réalisé via le DataColumn indexeur):

 HashSet<int> ids = new HashSet<int>(); 
     DataColumn col = table.Columns["ID"]; 
     foreach (DataRow row in table.Rows) 
     { 
      ids.Add((int)row[col]); 
     } 
     var missing = list.Where(item => !ids.Contains(item.ID)).ToList(); 
+0

Je n'ai pas testé les deux approches mais diriez-vous que votre réponse est plus efficace que celle de bdowden? – Jon

+0

Il n'y aura pas grand-chose à moins que vous ayez d'énormes volumes, mais ** marginalement **. L'indexeur de chaîne effectue une recherche de la colonne pour chaque ligne. Dans la plupart des cas, respectez l'approche que vous trouvez la plus simple et la plus compréhensible (optimisez davantage seulement si nécessaire). –

+0

Oh, et il y a plus d'énumérateurs (= plus de frais généraux) dans la distribution/sélection, mais encore une fois: cela ne fera pas * normalement * une différence significative. –