Filtrer datatable avec linq

Filtrer datatable avec linq - C#/.NET managed - Programmation

Marsh Posté le 10-12-2014 à 04:39:14    

Bonjour,
j'ai une datatable avec une liste de clients que je veux filtrer donc je fais ceci
 

Code :
  1. da.Fill(dt);
  2.             if (SearchLabel.Text != "" )
  3.             {
  4.                 dt.AsEnumerable().Where(r => r.Field<string>("name" ).Contains(SearchLabel.Text));
  5.             }


 
Seulement dt n'est pas filtré et si j'appelle la methode CopyToDataTable pour copier le résultat dans une autre datatable j'ai un message Collection was modified; enumeration operation might not execute.
Vous pouvez m'expliquer ce que je fais mal ?


---------------
Instagram - Mon PVT en Australie.
Reply

Marsh Posté le 10-12-2014 à 04:39:14   

Reply

Marsh Posté le 10-12-2014 à 12:32:07    

Je créerais un IEnumerable<DataRow> que j'utiliserais pour filtrer / recopier
 
Dans ton code, tu filtres "dans le vide", puisque tu ne fais rien des données filtrées (dt.AsEnumerable().Where.... n'a aucun impact sur dt).
 
 

Code :
  1. da.Fill(dt);
  2. var dataRows = dt.AsEnumerable();//dataRows est un IEnumerable<DataRow>
  3. if (!string.IsNullOrEmpty(SearchLabel.Text))// ou IsNullOrWhiteSpace
  4.     dataRows = dataRows.Where(x => x.Field<string>("name" ).Contains(SearchLabel.Text));//il faut setter à nouveau dataRows, bien sûr
  5. //etc si tu as d'autres filtres à passer
  6. var newDataTable = dataRows.CopyToDataTable();


 
Pour ton message "collection was modified", ça sent le foreach avec des suppressions d'éléments... Mais je ne vois pas ça dans le code que tu donnes, donc difficle à dire.

Message cité 1 fois
Message édité par deliriumtremens le 10-12-2014 à 21:26:57
Reply

Marsh Posté le 10-12-2014 à 21:26:01    

De mémoire :

 

- CopyToDataTable() est sensé fonctionner, je ne vois pas pourquoi tu rencontres cette erreur, ça vaut le coup de creuser un peu je pense.

 

- Sinon, si c'est pour de l'affichage, utilise un DataView qui te propose d'écrire des filtres en quasi-SQL.

Code :
  1. DataView dv = new DataView(dt);
  2. dv.RowFilter = "truc = 1 OR truc = 2";


Cette classe peut être bindée à la plupart des contrôles genre datagrid, etc

 

- En .Net 3.5 tu as aussi des trucs intéressants dans DataTableExtensions.

 

Bon courage !! (je déteste les datatables et tout ce qui s'y rapporte, j'espère ne plus jamais en revoir).

Message cité 1 fois
Message édité par TotalRecall le 10-12-2014 à 21:28:33

---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
Reply

Marsh Posté le 11-12-2014 à 01:36:00    

deliriumtremens a écrit :

Je créerais un IEnumerable<DataRow> que j'utiliserais pour filtrer / recopier
 
Dans ton code, tu filtres "dans le vide", puisque tu ne fais rien des données filtrées (dt.AsEnumerable().Where.... n'a aucun impact sur dt).
 
 

Code :
  1. da.Fill(dt);
  2. var dataRows = dt.AsEnumerable();//dataRows est un IEnumerable<DataRow>
  3. if (!string.IsNullOrEmpty(SearchLabel.Text))// ou IsNullOrWhiteSpace
  4.     dataRows = dataRows.Where(x => x.Field<string>("name" ).Contains(SearchLabel.Text));//il faut setter à nouveau dataRows, bien sûr
  5. //etc si tu as d'autres filtres à passer
  6. var newDataTable = dataRows.CopyToDataTable();




Avec ce code :

Code :
  1. DataTable dt = new DataTable();
  2. da.Fill(dt);
  3. DataTable resultDt = new DataTable();
  4. resultDt = dt.Copy();
  5. var dataRows = dt.AsEnumerable();
  6.             if (SearchLabel.Text != "" )
  7.             {
  8.                 dataRows = dataRows.Where(x => x.Field<string>("name" ).Contains(SearchLabel.Text));
  9.             }
  10.             dataRows.CopyToDataTable(resultDt, LoadOption.PreserveChanges);


J'ai toujours la liste complète des résultats, on dirait qu'il ne tient pas compte du filtre.

TotalRecall a écrit :

De mémoire :
 
- CopyToDataTable() est sensé fonctionner, je ne vois pas pourquoi tu rencontres cette erreur, ça vaut le coup de creuser un peu je pense.
 
- Sinon, si c'est pour de l'affichage, utilise un DataView qui te propose d'écrire des filtres en quasi-SQL.

Code :
  1. DataView dv = new DataView(dt);
  2. dv.RowFilter = "truc = 1 OR truc = 2";


Cette classe peut être bindée à la plupart des contrôles genre datagrid, etc
 
- En .Net 3.5 tu as aussi des trucs intéressants dans DataTableExtensions.
 
Bon courage !! (je déteste les datatables et tout ce qui s'y rapporte, j'espère ne plus jamais en revoir).


Je voudrais jouer un peu avec linq donc j'essaie de faire fonctionner le code plutot que d'utiliser un dataview. ;)


---------------
Instagram - Mon PVT en Australie.
Reply

Marsh Posté le 11-12-2014 à 07:36:39    

Ben oui.
 
Tu copies ton datatable source dans la destination :  
 

Code :
  1. resultDt = dt.Copy()


 
Ce qui copie structure ET données !
 
Donc... essaie de créer la deuxième dataTable simplement avec CopyToDataTable, comme dans le code que j'ai montré
 
 

Code :
  1. DataTable resultDt = dataRows.CopyToDataTable(); //à faire après application du filtre, bien sûr


Message édité par deliriumtremens le 11-12-2014 à 07:37:24
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed