none
Wie ColumnName von bestimmten DataColumns mit LINQ selektieren? RRS feed

  • Frage

  • Hallo,
    nochmals eine Frage zu DataColumn und LINQ.
    In einer DataTable suche ich nach nach Spalten, dessen Caption einen bestimmten Teilstring enthält.
    Von diesen Spalten benötige ich den ColumnName, um diese dann später darüber auswählen zu können (TableErgebnisse.Columns["ColumnName"]).
    Da in der Tabelle mehrere Spalten die Bedingung erfüllen können, sollen die ColumnNames in einer Liste gespeichert werden.


    Mit foreach kann man sicherlich alle Spalten durchlaufen.

    List<string> columnNames = new List<string>();
    foreach (DataColumn column in TableErgebnisse.Columns)
    {
      // wenn "...x..." oder "...y..." mit "...mm..." als Caption existiert
      if (((column.Caption.IndexOf("x") > -1) || (column.Caption.IndexOf("y") > -1)) && (column.Caption.IndexOf("mm") > -1))
      {
        columnIndex.Add(column.ColumnName);
      }
    }


    Wie kann ich das mit LINQ lösen?

    Alexander

    Mittwoch, 25. Mai 2011 17:04

Antworten

  • Hallo Alexander,

    hier ist mal ein Stückchen völlig ungetesteter, aber zumindest kompilierbarer, Code. Ich hoffe das hilft dir weiter.

    var columnNames =
            table.Columns
              .Cast<DataColumn>()
              .Where(x =>
                  (x.Caption.IndexOf("x") > -1 || x.Caption.IndexOf("y") > -1)
                  && x.Caption.IndexOf("mm") > -1)
              .Select(x => x.ColumnName);
    

     

    Gruß
    Philip 

    • Als Antwort vorgeschlagen Frank Dzaebel Donnerstag, 26. Mai 2011 11:21
    • Als Antwort markiert AlexanderRi Donnerstag, 26. Mai 2011 14:01
    Donnerstag, 26. Mai 2011 09:55
  • Hallo Alexander,

    sehe ich genauso als das günstigste - noch ein ToList und man hat auch einen List<string>:

       DataTable tableErgebnisse = new DataTable();
       string[] spalten = { "Erste", "mit y", "x mit mm", "Xavier", "y mit mm", "nochein y" };
       foreach (var spalte in spalten) tableErgebnisse.Columns.Add(spalte);
    
       List<string> columnNamen = tableErgebnisse.Columns.Cast<DataColumn>().Where(
        c=>(c.Caption.IndexOf("x") > -1) || (c.Caption.IndexOf("y") > -1)
         && (c.Caption.IndexOf("mm") > -1)).Select(x=>x.ColumnName).ToList();
    


    ciao Frank
    • Als Antwort markiert AlexanderRi Donnerstag, 26. Mai 2011 14:01
    Donnerstag, 26. Mai 2011 11:23

Alle Antworten

  • Hallo Alexander,

    hier ist mal ein Stückchen völlig ungetesteter, aber zumindest kompilierbarer, Code. Ich hoffe das hilft dir weiter.

    var columnNames =
            table.Columns
              .Cast<DataColumn>()
              .Where(x =>
                  (x.Caption.IndexOf("x") > -1 || x.Caption.IndexOf("y") > -1)
                  && x.Caption.IndexOf("mm") > -1)
              .Select(x => x.ColumnName);
    

     

    Gruß
    Philip 

    • Als Antwort vorgeschlagen Frank Dzaebel Donnerstag, 26. Mai 2011 11:21
    • Als Antwort markiert AlexanderRi Donnerstag, 26. Mai 2011 14:01
    Donnerstag, 26. Mai 2011 09:55
  • Hallo Alexander,

    sehe ich genauso als das günstigste - noch ein ToList und man hat auch einen List<string>:

       DataTable tableErgebnisse = new DataTable();
       string[] spalten = { "Erste", "mit y", "x mit mm", "Xavier", "y mit mm", "nochein y" };
       foreach (var spalte in spalten) tableErgebnisse.Columns.Add(spalte);
    
       List<string> columnNamen = tableErgebnisse.Columns.Cast<DataColumn>().Where(
        c=>(c.Caption.IndexOf("x") > -1) || (c.Caption.IndexOf("y") > -1)
         && (c.Caption.IndexOf("mm") > -1)).Select(x=>x.ColumnName).ToList();
    


    ciao Frank
    • Als Antwort markiert AlexanderRi Donnerstag, 26. Mai 2011 14:01
    Donnerstag, 26. Mai 2011 11:23
  • Hallo Alexander,

    Bei häufiger Verwendung lohnt es sich eine Erweiterungsmethode zu schreiben und das Ganze etwas objektorientierter zu gestalten. Dann könntest Du nämlich Anweisungen wie: tableEreignisse.GetColumnsContaining( new[] {"x", "y"}, "mm") schreiben und sowohl die Matching-Liste (x, y) als auch den vorausgesetzten String (mm) je nach Anforderung variieren:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Data;
    
    namespace ConsoleApplication1 {
      class Program {
        static void Main(string[] args) {
          // Tabelle erstellen
          DataTable tableEreignisse = new DataTable();
          DataColumn[] columns = new DataColumn[] {
    		new DataColumn("Column_1"),
    		new DataColumn("Column_mm_x"),
    		new DataColumn("Column_y"),
    		new DataColumn("Column_mm_2")
    	    };
    
          tableEreignisse.Columns.AddRange(columns);
    
          // Spaltennamen-Abfrage definieren
          var columnNames = tableEreignisse.GetColumnsContaining( new[] {"x", "y"}, "mm");
    
          // Spaltennamen abfragen und ausgeben
          foreach (string columnName in columnNames)
            Console.WriteLine(columnName);
    
          Console.ReadKey(true);
        }
      }
    
      public static class DataTableExtensions {
        public static List<string> GetColumnsContaining(this DataTable table, IEnumerable<string> lookupList, string requiredString) {
          var queryAllColumnNames = from DataColumn c in table.Columns select c.ColumnName;
          var queryMatchingColumnNames = from m in queryAllColumnNames
                          from l in lookupList
                          where m.Contains(l) && m.Contains(requiredString) // oder: m.StartsWith(l) oder m.EndsWith(l)
                          select m;
    
          return queryMatchingColumnNames.ToList();
        }
      }
    }
    
    

    Gruß
    Marcel

    Donnerstag, 26. Mai 2011 12:38
    Moderator