Announcement

Collapse
No announcement yet.

Objekte dynamisch erzeugen - wie bei new in linq

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Objekte dynamisch erzeugen - wie bei new in linq

    Hallo!

    Ich habe des öfteren den Fall, dass ich aus einer CSV-Datei Daten einlesen muss. Da die enthaltenen Tabellen meist gleich sind, wäre es gut wenn ich daraus dynamisch Objekte erstellen könnte.
    Leider kann ich das nicht implementieren, da einige Spalten vom User erzeugt werden können (Namen und Inhalt).

    Beispiel:
    $Knoten:Nr;Name;XKoord;YKoord;User1
    1;Kreuzung Hauptstr;49.3333;8.5443;Eingabe von xy

    User1 ist das vom Benutzer erstellte Attribut, welches optional ist.

    Mit Linq könnte ich zwar folgendes machen nach dem ich es mit Split zerlegt habe:

    Code:
    var values = table.Select(c => new { No = c[0], Name = c[1], XCoord = c[2], YCoord = c[4] };
    Mein Benutzerdefiniertes Attribut bleibt aber auf der Strecke!

    Kann ich folgendes machen?

    Code:
    Dictionary<string, int> columns; // column["No"] = 0, ... column["User1"] = 5
    
    var values = table.Select(c => new { No = c[0], Name = c[1], XCoord = c[2], YCoord = c[4], column[5] = c[5] };
    Das Dictionary erzeuge ich aus dem Tabellen-Header. Wichtig wäre aber column[5] = c[5] damit ich "User1" als Property habe.


    Vielen Dank,
    Tucca

  • #2
    Also ich kann mir nicht vorstellen, dass man (ohne große Umwege über Reflection o.ä.) dynamisch zur Laufzeit strong typed datentypen anlegen kann.
    Macht ja auch gar keinen Sinn, denn Du kannst die Variable ja auch nicht verwenden, wenn die dann bei einer Datei mal nicht drin ist.
    Da musst Du Dir eine dynamische Struktur ausdenken.

    Ausserdem sehe ich da auch keinen Split, sondern wahrscheinlich eine DataTable (variable table) mit wahrscheinlich einem Microsoft Text Reader als Connection

    Comment


    • #3
      Hallo,

      Da die enthaltenen Tabellen meist gleich sind, wäre es gut wenn ich daraus dynamisch Objekte erstellen könnte.
      Wenn sie meist gleich sind kannst du für den Standardfall statisch programmieren

      Es können zwar anonyme Klassen verwendet werden aber Objekt so dynamisch zu erstellen geht AFAIK nur mit Reflektion/ILEmit.

      Die Abfrage kannst du jedoch dynamisch erzugen wenn per OleDB auf die CSV zugegriffen wird. Genauer gesagt kann das SQL Statement dynamisch erstellt werden.
      [highlight=c#]
      DataTable dt = new DataTable();
      string conn = @"Provider=Microsoft.Jet.OLEDB.4.0;" +
      @"Data Source=" +
      Path.GetDirectoryName(Assembly.GetExecutingAssembl y().Location) +
      @";Extended Properties=""Text;HDR=No;FMT=Delimited""";
      using (OleDbConnection connection = new OleDbConnection(conn))
      {
      OleDbCommand cmd = new OleDbCommand(
      @"SELECT * FROM data.csv", connection);
      OleDbDataAdapter da = new OleDbDataAdapter(cmd);
      connection.Open();
      da.Fill(dt);
      connection.Close();
      }
      [/highlight]
      Als Resultat hast du eine DataTable. Diese kann mir LINQ weiterverarbeitet werden.

      Oder:
      [highlight=c#]
      static void Main(string[] args)
      {
      using (StreamReader sr = File.OpenText("Data.csv"))
      {
      var query =
      from row in GetRows(sr, ";")
      select row;
      }
      }
      //---------------------------------------------------------------------
      public static IEnumerable<string[]> GetRows(StreamReader sr, string delim)
      {
      while (!sr.EndOfStream)
      yield return sr.ReadLine().Split(delim.ToCharArray());
      }
      [/highlight]

      Liefert dir alle Spalten. Nur die du brauchst kannst du weiterverwenden.

      Wenn die Daten gelesen sind ist auch der Header bekannt und dann würde ich das dynamische Mapping durchführen.


      mfG Gü
      "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

      Comment


      • #4
        Hi !

        Vielen Dank für die Antworten.

        @gfoidl: Die zweite Variante habe ich schon im Einsatz. Die Möglichkeit über einen "DB-Provider" kannte ich zwar, war mir dieser aber nicht mehr ganz bewusst...

        Vielleicht versuch ich's damit.

        Die Grund-Objekte sind statisch programmiert. Mein Problem sind aber die Benutzerdefinierten Attribute die ich bei der Programmierung nicht kenne (weder Typ noch Name).

        Für weitere Idee bin ich gerne offen!

        Gruß,
        Tucca

        Comment

        Working...
        X