Laden...

Code aus String ausführen --> Objekte zur Laufzeit verändern

Erstellt von gagagurge vor 9 Jahren Letzter Beitrag vor 9 Jahren 2.296 Views
G
gagagurge Themenstarter:in
3 Beiträge seit 2015
vor 9 Jahren
Code aus String ausführen --> Objekte zur Laufzeit verändern

Hallo zusammen,

da ich jetzt einige Tage damit verbracht habe eine "passende" Lösung zu finden, habe ich mich, in der Hoffnung Hilfe zu bekommen, hier angemeldet .

Ich habe noch nicht die "Mega Erfahrungen" oder schreibe superschönen sauberen Code, aber Übung macht den Meister 🙂 Auch meine Ausdrucksweise ist vielleicht beim 1. mal Lesen auch nicht super toll verständlich, aber ich bemühe mich wirklich 🙂

Zum eigentlichen Thema:

Der Titel ist vielleicht nicht gerade optimal aber ich wollte jetzt keinene Roman rein schreiben.
Ich habe angefangen eine KFZ Werkstätten WPF Applikation zu entwickeln. + MS SQL Datenbank.

Ursprünglich wollte ich das ganze wie in Java mit EJB aufziehen aber ehrlich gesagt ist mir das ganze in C# etwas zu kompliziert 🙁 --> Mit offenen Armen und dankend nehme ich hier JEDE Hilfe gerne entgegen!!
Also habe ich mich für eine Quick and Dirty Version mit sturren Strings die SQL Anweisungen enthalten entschieden.

Um das ganze etwas "dynamischer" zu machen hatte ich folgende Idee:
Ich schreibe eine Methode in meiner super Klasse meiner Datenhaltungsklassen(Auto, Kunde, Marke, Modell,...) die mir mittels Reflection alle Attribute ausgibt. Danach bastle ich mir dynamisch ein Select zusammen (auch über mehrere Tabllen bzw. Datenhaltungs-Klassen.

So, jetzt habe ich ein SqlDataReader Objekt das zb eine Zeile aber ca 50 Spalten enthält. (Habe die Header der Spalten dynamisch erstellt um beim Auslesen dynamisch differenzieren zu können)

Ich bastle mir aus diesem SqlDataReader-Objekt jetzt meine Strings mit den Ausführungen zusammen.

Tja, nur dummerweise sind in diesen Strings Anweisungen drinnen die speziell geladene/bereits vorhandene Objekte verändern wollen.

BSP:
Ich habe eine Klasse KundeDlg.xaml.cs die im Vordergrund ein WPF Fenster hat.
In dieser KundeDlg.xaml.cs Klasse habe ich eine List<Kundenautos> und eine List<Autoliste>.
Kundenautos und Autoliste sind jeweils Datenhaltungs-Klassen und bestehen nur aus einem Konstruktor + Attribute mit get und set.

Über ein anderes Fenster suche ich in der DB nach einem Kunden und wähle diesen aus.
Jetzt möchte ich diese 2 erwähnten Listen "befüllen" um alle Autos eines Kunden anzuzeigen und mit den Daten weiter zu arbeiten. Dazu habe ich mir eben diese "dynamisch erstellten Anweisungs-Strings" erstellt.
Ich befinde mich so gut wie durchgehend in der Klasse KundeDlg.xaml.cs die im Namespace "MyWerkstatt" und im Unterordner "GUI" ist. Meine Datenhaltungsklassen befinden sich auch in "MyWerkstatt.Datenhaltung". Und jetzt möchte ich eben hier in KundeDlg.xaml.cs diese erstellten Anweisungen ausführen.
--> Bisher klappt das ja auch ganz gut, im Sinne von: Die Anweisungen in den Strings stimmen, da ich sie unter "normaler" Anwendung ausführen kann.

zb:


Autoliste.Add(new Auto()); //Autoliste wird im Konstruktor von KundeDlg.xaml.cs erstellt
Kundenautos.Add(new Kundenautos()); //Kundenautos wird im Konstruktor von KundeDlg.xaml.cs erstellt
Autoliste[0].ID=1;
Autoliste[0].Baujahr=2000;
Autoliste[0].PS=200;
Autoliste[0].Kommentar= "asdfadsfasdfasdfadsf";
Autoliste[0].Pickerl=new DateTime(2015,1,28);
Autoliste[0].Marke.ID=1;
Autoliste[0].Marke.Name= "VW";

Kundenautos[0].ID=1;
Kundenautos[0].AutoID=1;

Der Teil wo ich auf die Schnauze fliege:


CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters parameters = new CompilerParameters();
            
parameters.GenerateInMemory = true;
parameters.ReferencedAssemblies.Add("System.dll");
parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
parameters.ReferencedAssemblies.Add("System.Data.dll");

Dann bastle ich mir mit einem StringBuilder sb den auszuführenden String:


StringBuilder sb = new StringBuilder();
sb.AppendLine(@"using System;");
sb.AppendLine(@"using System.Windows.Forms;");
sb.AppendLine(@"using MyWerkstatt;"); // <-- Kennt er nicht
sb.AppendLine(@"using MyWerkstatt.GUI;"); // <-- Kennt er nicht
sb.AppendLine(@"using MyWerkstatt.Datenhaltung;"); // <-- Kennt er nicht
sb.AppendLine(@"using System.Collections.Generic;");
sb.AppendLine(@"using System.Text;");
sb.AppendLine(@"using System.Threading.Tasks; ");
sb.AppendLine(@"using System.Windows; ");
sb.AppendLine(@"namespace MyWerkstatt"); // <-- Fehler
sb.AppendLine(@"{");
sb.AppendLine(@"public class Test{");
sb.AppendLine(@"public Test(){"); //habe im Netz gelesen man sollte mal versuchen einen Konstr anzulegen und dort die Objekte zu erstellen
sb.AppendLine(@"KundeDlg dlg ;"); // <-- Er kennt KundeDlg nicht.
sb.AppendLine(@"List<Kundenautos> Kundenautos ;"); // <-- Auch meine Datenhaltungsklassen nicht
sb.AppendLine(@"List<Auto> Autoliste ;");
sb.AppendLine(@"dlg = new KundeDlg();");
sb.AppendLine(@"Kundenautos = dlg.Kundenautos;");
sb.AppendLine(@"Autoliste = dlg.Autoliste;}");
sb.AppendLine(@"public void Funktion(){");
foreach(String s in befehle)
{
     sb.AppendLine(s); //hier sind die Befehle wie oben beschrieben, nur halt in Strings verpackt :)
}
sb.AppendLine(@"}}}"); // Schließe Methode, Class und Namespace

Zum Schluss noch das "ausführen":

CompilerResults result = provider.CompileAssemblyFromSource(parameters, sb.ToString());

Ähm, ja, hier ist das result schön mit Errors bepackt.
Meist: Compiler Error CS0234 und Compiler Error CS0246

Was mache ich falsch? und noch wichtiger: Könnt ihr mir einigermaßen folgen? 🙂

Wenn einer meint: Hey, löse doch das ganze mit Entities --> GERNE !!! nur wie?? 🙁
Oder: Gib mal mehr Infos! --> Gerne, nur welche? 🙂

Oder: Das ist absoluter Schrott! --> Ok, zeig mir bitte wie ich es besser Lösen kann.

Sorry für diesen Roman, nur ich denke mir, je besser ich mein Problem schildere, desto besser kann mir geholfen werden...

Danke schon mal fürs Lesen und ich freue mich über konstruktive und brauchbare Antworten 🙂
MFG gagagurge

K
89 Beiträge seit 2013
vor 9 Jahren

Also habe ich mich für eine Quick and Dirty Version mit sturren Strings die SQL Anweisungen enthalten entschieden.

Schau doch mal nach LINQ to SQL und Dynamic LINQ ExpressionBuilder

Also du willst dein Tool kompilieren verstehe ich das richtig?
Wieso holst du dir zum kompilieren nicht einen Compiler?
Wenn du Fehlermeldungen hast, kopiere sie, wie du es hier getan, füge sie in google ein und schon wird dir eine mögliche Ursache der Probleme genannt 😉
Beispiel: Compiler Error CS0234

G
gagagurge Themenstarter:in
3 Beiträge seit 2015
vor 9 Jahren

Danke aber für die schnelle Antwort!!

Schau doch mal nach LINQ to SQL und Dynamic LINQ ExpressionBuilder

Ok ich versuche es mal so, danke! Falls dir dazu ein Tipp/Beispiel für meinen Konkreten Fall einfällt, immer her damit 😃

Also du willst dein Tool kompilieren verstehe ich das richtig?
Wieso holst du dir zum kompilieren nicht einen Compiler?

Ja ich möchte mein Tool kompilieren, es lässt sich ja auch kompilieren nur eben der Teil mit den Befehlen nicht..
Wie meinst du das mir einen Compiler holen?

Wenn du Fehlermeldungen hast, kopiere sie, wie du es hier getan, füge sie in google ein und schon wird dir eine mögliche Ursache der Probleme genannt 😉
Beispiel:
>

Naja, das habe ich ja auch gemacht, und das hat mir für vorherige Fehler ja auch geholfen, aber dieses Beispiel ist ja nicht wirklich hilfreich für mich 😃

K
89 Beiträge seit 2013
vor 9 Jahren

Um dich mit LINQ-Abfragen zu beschäftigen würd eich dir das openbook vom ehemaligen Verlag GalileoComputing (mittlerwiel Rehinwekr Computing) empfehlen.
Um deine LINQ-Filter dynamisch zu generieren finde ich den Artikel Build Where Clause Dynamically in Linq gut.

Naja zum Beispiel kannst du deinen Code ja mit Visual Studio kompilieren. Da brauchst du keinen extra Code schreiben.
Von VS gibt es die Express-Version, die wenn ich mich nicht irre kostenlos ist.

G
gagagurge Themenstarter:in
3 Beiträge seit 2015
vor 9 Jahren

Um dich mit LINQ-Abfragen zu beschäftigen würd eich dir das openbook vom ehemaligen Verlag GalileoComputing (mittlerwiel Rehinwekr Computing) empfehlen.
Um deine LINQ-Filter dynamisch zu generieren finde ich den Artikel
>
gut.

Danke für den Tipp, Galileo Bücher sind immer TOP!

Naja zum Beispiel kannst du deinen Code ja mit Visual Studio kompilieren. Da brauchst du keinen extra Code schreiben.
Von VS gibt es die Express-Version, die wenn ich mich nicht irre kostenlos ist.

Ich benutze ja VS2013 ... Habe ich wohl offensichtlich nicht erwähnt. Sorry..

2.921 Beiträge seit 2005
vor 9 Jahren

Hallo gagagurge.

Diese Technik, die Du wahrscheinlich suchst, wird in den genannten Links verwendet bzw. beschrieben:

Search & Replace Tool
Funktionsplotter
Formeleditor
Prozesse in Console ausgeben.
Objekte an Laufzeit kompilierten Code übergeben oder auslesen (allgemeine Kommunikation)

Ich hoffe das hilft Dir weiter.

Sollte jemand noch weitere Ideen haben, sucht die besten Ergebnisse zusammen und postet sie hier.

dr4g0n76

EDIT: Und versuche mal bitte mehr anwendungstechnisch vorerst zu erklären, was Du tun möchtest. Vielleicht gibts ja eine ganz andere Lösung die gut passt.

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

F
10.010 Beiträge seit 2004
vor 9 Jahren

Ich schreibe eine Methode in meiner super Klasse meiner Datenhaltungsklassen(Auto, Kunde, Marke, Modell,...) die mir mittels Reflection alle Attribute ausgibt. Danach bastle ich mir dynamisch ein Select zusammen (auch über mehrere Tabllen bzw. Datenhaltungs-Klassen.

Also einen ORMapper selber schreiben?
Wenn du eh keine Ahnung hast, warum den stress machen?
Und daraus ergibst sich dann wahrscheinlich der ganze andere rest.