Laden...

Einfacheren Weg gesucht für das Generieren von SQL Statements in C#

Erstellt von Trekki1990 vor 8 Jahren Letzter Beitrag vor 8 Jahren 1.088 Views
Trekki1990 Themenstarter:in
503 Beiträge seit 2008
vor 8 Jahren
Einfacheren Weg gesucht für das Generieren von SQL Statements in C#

Hallo liebe Community,

ich habe eine Anwendung die Daten in eine SQL Datenbank (MS) schreibt. Das habe ich bisher über Parameter gemacht. Das soll auch so bleiben. Nur ist mir das Tippen des SQL-Befehls zu aufwendig und fehleranfällig (Thema Kommas usw...). Ich habe mir eine Funktion gebaut die mir den SQL String zusammenbaut. Gibt's hier eine elegantere Lösung als die meine? Ich habe das Ganze auch dynamisch gehalten (mal 2 - 3 Paramater, aber auch viele mehr sind möglich), weil ich die Funktion in einer Klasse verwende.

Was auch nicht mit dieser Methode geht sind unterschiedliche Datentypen. So kann ich alles nur als String übergeben. Aber vielleicht habe ich hier generell einen Denkfehler oder den falschen Ansatz. Über Google habe ich schon viel gesucht, aber nicht wirklich etwas finden können, was mir weiterhilft.

So sieht meine Funktion aus:


// SQL Funktion INSERT
        public void SQL_INSERT_INTO(string table, string[] columns, string[] values, bool where, string where_command)
        {
            string col = "INSERT INTO " + table + " (";
            int col_anzahl_columns1 = columns.Length;
            foreach (string c in columns)
            {
                col = col + c;
                if (col_anzahl_columns1 > 1) col = col + ",";
                col_anzahl_columns1--;
            }

            col = col + ") VALUES (";

            int col_anzahl_columns2 = columns.Length;
            foreach (string c in columns)
            {
                col = col + "@" + c;
                if (col_anzahl_columns2 > 1) col = col + ",";
                col_anzahl_columns2--;
            }

            col = col + ")";

            if (where == true) col = col + " WHERE " + where_command;

            SqlConnection connection = new SqlConnection(sqlconnection);
            SqlCommand cmd = new SqlCommand();
            cmd.CommandText = col;
            cmd.Connection = connection;
            int i = 0;
            foreach (string v in values)
            {
                cmd.Parameters.AddWithValue("@" + columns[i], v.ToString());
                i++;
            }
            cmd.Connection.Open();
            cmd.ExecuteNonQuery();
            cmd.Connection.Close();
            cmd.Connection.Dispose();
        }

Viele Grüße
trekki

16.807 Beiträge seit 2008
vor 8 Jahren

Ich weiß nicht, was das immer mit der Betonung auf "einfach" soll - oft ist Software eher kompliziert. 🤔
Sonst könnte es ja jeder.

Warum nimmst Du nicht einen entsprechenden ORM Mapper?
Und klar gibts dafür elegantere Wege, zB. Reflection oder TypeDescriptor.

Du solltest auch Deinen Code modularisieren. 👍
Willst Du wirklich in jeder Methode das Foreach für das Zusammenbauen der Values ausprogrammieren? Da is ja quatsch. =)
Zudem ist Dein Code absolut nicht testbar und verletzt auch Grundregeln wie Single Responsibility.

Das hier ist mein Code in Zusammenhang mit Dapper:

public String InsertWithParameters<TEntity>( string tableName )
{
    if( String.IsNullOrEmpty( tableName ) ) throw new ArgumentNullException( nameof( tableName ) );

    IList<string> propNames = GetPropNames<TEntity>();
    return $"INSERT INTO [{tableName}] ({CreateFieldJoin( propNames )}) VALUES ({CreateValueJoin( propNames )});";
}

CreateFieldJoin erzeugt den ersten Teil gemäß nach [Field1],[Field2],[Field3] und CreateValueJoin '@Field1','@Field2','@Field3'.
Es erzeugt nur den String mit Parametern. Es öffnet keine Verbindung, es führt nichts aus. Es macht nur das, wofür es zuständig ist.

Aber ich würde das immer vermeiden, wenn ich einen ORM verwenden kann. 👍

3.825 Beiträge seit 2006
vor 8 Jahren

Hallo,

ja, SQL Kommandos schreiben ist lästig, zeitraubend und fehleranfällig.

Ich lasse das den CommandBuilder von .NET machen :

SqlConnection conn = new SqlConnection(...);
SqlCommand cmd = new SqlCommand(...);
SqlDataAdapter da = new SqlDataAdapter(cmd);
SqlCommandBuilder cb = new SqlCommandBuilder(da);    // Hier werden SQL Kommandos für Insert, Update und Delete erzeugt

DataSet ds = new DataSet();
...
ds.Tables["Customers"].Rows.Add(...);
conn.Open();
da.Update(ds, "Customers")
conn.Close();

Intern arbeitet .NET auch mit Parametern, man kann sich die erzeugten SQL-Befehle anschauen.

Beispiele dazu findest Du im Netz oder in dem Text in meiner Signatur.

Wenn Du überhaupt nichts mehr mit SQL zu tun haben willst dann benutze ein ORM wie Entity Framework oder ein Micro ORM wie Dapper oder PetaPoco.

Ich benutze ein eigenes ORM, da würde das so aussehen :


DataObjectsAddresses ad = new DataObjectsAddresses();
ad.number = 10000;
ad.name = "Fritz GmbH";
ad.city = "Frankfurt";
ad.InsertRow();

Hinweis : In deinem Code wandelst Du alle Werte in String um. Das geht spätestens bei Datum, Zeit und numerischen Werten schief wenn der SQL Server auf englisch steht. Du musst Objekte übergeben und dann den Parameter mit dem richtigen Typ übergeben.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

Trekki1990 Themenstarter:in
503 Beiträge seit 2008
vor 8 Jahren

Vielen Dank für euren Denkanstoß! 😃
Habe mich in LINQ eingelesen. Funktioniert super.

Viele Grüße
trekki