Announcement

Collapse
No announcement yet.

Wie Datentyp einer Variable festlegen aus String (z.B. in einer Datei)

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

  • Wie Datentyp einer Variable festlegen aus String (z.B. in einer Datei)

    Hi @ll..

    bin jetzt schon seit Tagen an einem kleinen dummen Problemchen dran und komm nicht drauf *grr*

    Ich will einen String in einen Datentyp umwandeln und diesen dann für die Initialisierung einer Variable verwenden:

    Kurz als ALLGEMEINES Beispiel:
    Ich habe einen String z.B. "System.Int32", z.B. geschrieben in einer Textdatei.

    Nun will ich eine Variable anlegen, mit diesem Wert
    Code:
    Dim s as String = "System.Int32"
    Dim x as s
    Das ist klar dass dies nicht funktioniert, aber nur zum allgemeinen Verständnis was ich machen will.
    Den Typ aus einem String lässt sich ja so ermitteln:

    Code:
    Type.GetType("System.Int32")
    Nur bei vielen Externen Klassen bekomm ich eben den Fehler auf eine nicht Inizialierte Objektinstanz.

    Mir geht es hauptsächlich darum.
    Mit dem SQL SMO will ich einen Datenbank aus einer Konfigurationsdatei (Text oder xml) erstellen.
    In der Datei steht der Spalenname und der Datentyp
    --> z.B.
    <item columnname="Testspalte1" typ="BigInt">
    <item columnname="Testspalte2" typ="NVarChar(20)">


    Über das Microsoft.SqlServer.Management.Smo erstelle ich eine Variable mit dem Column Datentyp

    Code:
    Dim col as Microsoft.SqlServer.Management.Smo.Column
    col = new Column(tabellenname, "Hier die Spalte aus der Textdatei z.B." & _
      "Testspalte1"
    col.Datatype = DataType.BigInt <<---
    Dort beim Datatype will ich den Wert aus der Textdatei hernehmen.
    Probiert habe ich schon

    Code:
    col.Datatype = Type.GetType("DataType.BigInt")
    Aber das klappt nur mit den Systemwerden z.B. "System.String" "System.Int32" usw..
    Ansonten bekomme ich immer die Fehlermeldung auf die fehlende Objektinstanz.

    über CType gehts auch nicht, da nimmt ers mir nicht an
    z.B. über das erstellen einer irrelevanten Variable, und die über CType umwandeln und dann über GetType wieder den Datentyp herzugbekommen.

    Code:
    1. 
    CType(Variable, Type.GetType("System.String")) <-- Geht nicht
     
    2.
    Dim t as Type
    t = Type.GetType("System.String")
    CType(Variable, t) <-- Geht auch nicht (auch nicht beim Festlegen einer _
      Variable z.B. x = [...])
     
    3. 
    Dim o as Object
    Dim x as String = ""
    x = CType(o, Type.GetType("System.String"))
    Klasse.Datentype = x.GetType()
    <-- Das war meine Eigentlich Idee
    Fall Ihr mir jetzt vlt sagen wollt, nimm doch ein SQL-Skript, dann muss ich ablehnen. Es soll über das SMO gehen.

    Auch bitte keine Kommentare wie, Bitte nimm doch für die String umwandlung oder Integer Umwandlung CInt, CStr.. Das ist mir alles klar.. aber es geht mir hierbei um die Datenbankerstellung und um das Allgemeine.
    Irgendwie musss es ja funktionieren..
    Aber nach langen langen Versuchen hab ichs einfach nicht hinbekommen..

    Vlt hat das schon mal jemand so ähnlich gemacht, wie ich es machen will oder weiß jemand ne lösung.

    Schon mal vielen vielen Dank im Voraus

    mfg -=nEuDy=-

  • #2
    Hallo und willkommen,

    untersuche einmal, ob Activator.CreateInstance dem entspricht, was Du Dir vorstellst. Nach dem Erstellen eines Objekts muss es noch gecastet werden, aber Du bekommst es jedenfalls über den Namen der Klasse.

    Jürgen

    Comment


    • #3
      Hallo Jürgen Thomas,

      erstmal Danke für die Antwort. Ich habe schon einiges mit deinem Vorschlag versucht, bin jedoch immer noch nicht zu einem vernünftigen Ergebnis gekommen.
      Mit dem Datentyp System.Int32 hab ich schon ein bisschern herumgespielt (um 2 Strings mit Zahlen zusammenzuzählen). Das klappt soweit. Aber sobald ich das mit meinen Namespaces die ich benötige versucht treten immer wieder unerwartete Fehler auf.
      Letztendlich will ich ja folgendes:
      Ich habe eine Stringvariable

      Code:
      Dim s as String 
      s = "DataType.BigInt"
      (Kompletter Namespace wäre Microsoft.SqlServer.Management.Smo.DataType BigInt)

      Und nun will ich sagen
      Code:
      Column.Datatype = s


      Versucht hab ich ein von einem Object diese Instance zu bilden
      Code:
      Dim x As Object = Activator.CreateInstance(Type.GetType("Microsoft.SqlServer.Management.Smo.DataType.BigInt"))
      Ich bin ja schon soweit, dass ichs so hinbekommen habe:
      Eine Instanz von Microsoft.SqlServer.Management.Smo.DataType gebildet
      Und alle Properties durchlaufen und hart abfragen ob "BigInt" usw..
      Ist aber keine schöne Lösung:
      Code:
      Dim pi As System.Reflection.PropertyInfo
      Dim dt As New Microsoft.SqlServer.Management.Smo.DataType
      
      For each pi in dt.GetType.GetProperties
        Select Case pi.Name
          Case "BigInt"
              Column.DataType = DataType.BigInt
          Case "NVarCharMax"
              Column.DataType = DataType.NVarCharMax
      [... usw ...]
        End Select
      Next
      Aber das ist absolut keine schöne lösung..
      Vorallem wenn ich ein NVarChar mit Länge angeben will.. das ist nämlich kein Property sondern ne Function.. d.h. ich kann in meiner Textdatei nicht sowas wie "NVarChar(20)" angeben

      Comment


      • #4
        Du musst das Objekt x aus dem vorletzten Code-Abschnitt noch in den richtigen Typ konvertieren. Unter C# geht es etwa so (Beispiel mit einem Formular CInstall):
        [highlight=c#]System.Reflection.Assembly aFrmAsm;
        Type aFrmType;
        // Assembly laden
        aFrmAsm = System.Reflection.Assembly.LoadFrom("V_Interna.Dll ");
        // Formular als Typ bestimmen, d.h. für mich Klasse für Formularaufruf
        aFrmType = aFrmAsm.GetType("JThomas.VSPolis.Interna.CInstall" );
        // diesen Typ erzeugen
        Object aFrmObj = Activator.CreateInstance(aFrmType);
        // konvertieren und direkt aktivieren;
        CInstall fInstall = aFrmObj as CInstall; // so ein Befehl fehlt bei Dir noch
        // erledige die Bearbeitung
        DialogResult dr = fInstall.Show();[/highlight]
        Unter VB wird (anstelle von as) noch CType benötigt; aber wie das geht, weißt Du sicher besser als ich.

        Jürgen

        Comment


        • #5
          Hallo,

          das mit dem kompletten Namespace sollte schon gehen (mit Punkt):
          Code:
          Microsoft.SqlServer.Management.Smo.DataType.BigInt
          Der komplette Namespace kann auch mit einem Reflector (zB http://www.red-gate.com/products/reflector/) ermittelt werden.

          Für das nvarchar-Problem:
          Bei bein OR-Mappern wird dies als System.String abgebildet, probiers mal.

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

          Comment


          • #6
            Hiho..

            erstmal Danke an alle.
            Den Reflector hab ich schon länger.. aber auf die Idee gekommen den zu Benutzen bin ich nicht
            Nur leider beim Einlesen der jeweilgen DLL(C:\Programme\Microsoft SQL Server\90\SDK\Assemblies\Microsoft.SqlServer.Smo.d ll) bekomm ich einen Scan Error und in den Anderen DLLs fin ich den Namen DataType nirgends.

            Mit Microsoft.SqlServer.Management.Smo.DataType.BigInt in der Creatinsance weder noch im Assebly.Load funktioniert es.

            Auch mit dem Beispiel von Jürgen Thomas bringt er mir immer einen Fehler, erkann keinen Standardkonstruktor finden.

            Bin wirklich am verzweifeln

            Comment


            • #7
              Hallo,

              hab mir den Aufbau von SMO mal angeschaut und gemerkt dass die Klasse DataType die Datentypen über statische Member offenlegt.

              Um den Datentyp zu ermitteln der per String gegeben ist kann zB dies verwendet werden
              [highlight=c#]
              string s = "BigInt";

              PropertyInfo pi = typeof(DataType).GetProperty(s);
              object dataTypeObject = pi.GetValue(null, null);
              DataType dataType = dataTypeObject as DataType;
              [/highlight]
              Bei GetValue wird deshalb null für das Objekt übergeben da die Eigenschaft statisch ist - ein Objektverweis könnte auch übergeben werden.

              Bleibt nur noch zu prüfen ob der String einen Datentyp als Eigenschaft oder als Methode anspricht.

              mfG Gü

              [highlight=vbnet]
              Dim s As String = "BigInt"

              Dim pi As PropertyInfo = GetType(DataType).GetProperty(s)
              Dim dataTypeObject As Object = pi.GetValue(Nothing, Nothing)
              Dim dataType As DataType = TryCast(dataTypeObject, DataType)
              [/highlight]
              Zuletzt editiert von gfoidl; 29.10.2008, 13:01.
              "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

              Comment


              • #8
                Hallo gfoidl,

                VIELEN VIELEN DANK!!! GENAU DAS WARS :-)

                Nur hab ich jetzt noch probleme, wenns anstatt eines Property eine Method ist (z.b. NVarChar)

                Bei NVarChar muss man ja ein Parameter(? heißt das so? oder ist das n Attribut?)) maxLength mit der maximalen Größe des Datentyps mitgeben.

                [highlight=vbnet]
                Dim s As String = "NVarChar"
                Dim pi As MethodInfo= GetType(DataType).GetMethod(s)

                Dim dataTypeObject As Object = pi.GetValue(Nothing, Nothing)
                Dim dataType As DataType = TryCast(dataTypeObject, DataType)
                [/highlight]

                Das hier in Zeile 5 geht ja nicht, und zweites muss ich ja irgendwie die maxLength als Wert zuvor mitgeben.

                Wie geht denn das?

                Schon mal Danke im Voraus und nochmal VIELEN DANK für die Hilfe

                mfg -=nEuDy=-

                Comment


                • #9
                  Hallo,

                  für nvarchar(n):
                  Code:
                  string s = "NVarChar(25)";
                  Regex regex = new Regex(@"\d+");
                  string s1 = s.Remove(s.IndexOf("("));
                  int n = int.Parse(regex.Match(s).Value);
                  
                  MethodInfo mi = typeof(DataType).GetMethod(s1);
                  object dataTypeObject = mi.Invoke(null, new object[] { n });
                  DataType dataType = dataTypeObject as DataType;
                  Anmerkung: Die Länge wird per Regex ermittelt. Eine Prüfung ob die Zahl (Länge) korrekt ist wird hier nicht durchgeführt.

                  mfG Gü

                  [highlight=vbnet]
                  Dim s As String = "NVarChar(25)"
                  Dim regex As New Regex("\d+")
                  Dim s1 As String = s.Remove(s.IndexOf("("))
                  Dim n As Integer = Integer.Parse(regex.Match(s).Value)

                  Dim mi As MethodInfo = GetType(DataType).GetMethod(s1)
                  Dim dataTypeObject As Object = mi.Invoke(Nothing, New Object() {n})
                  Dim dataType As DataType = TryCast(dataTypeObject, DataType)
                  [/highlight]
                  "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                  Comment


                  • #10
                    SUPER SUPER SUPER!!!

                    VIELEN DANK!

                    Es klappt :-) Genau das wollte ich. Aber ich muss sagen, trotz langer Programmiererfahrung (als Hobby) wäre nie auf diese Lösung gekommen.

                    Vielen Dank nochmal :-)

                    Comment

                    Working...
                    X