Die beste Methode zum Erstellen dynamischer SQL-Abfragen in C # /. NET3.5?

8

Ein Projekt, an dem ich gerade arbeite, beinhaltet das Refactoring eines C # -Com-Objekts, das als Datenbankzugriffsebene für einige Sql 2005-Datenbanken dient.

Der Autor des vorhandenen Codes hat alle SQL-Abfragen manuell mit einer Zeichenfolge und vielen if-Anweisungen erstellt, um die ziemlich komplexe SQL-Anweisung zu erstellen (~ 10 Joins, & gt; 10 Subselects, ~ 15-25, wo Bedingungen und GroupBy's ). Die Basistabelle ist immer dieselbe, aber die Struktur von Joins, Bedingungen und Gruppierungen hängt von einer Reihe von Parametern ab, die an meine Klasse / Methode übergeben werden.

Das Erstellen der SQL-Abfrage funktioniert zwar, aber es ist offensichtlich keine sehr elegante Lösung (und auch ziemlich schwer zu lesen / zu verstehen und zu warten) ... Ich könnte einfach einen einfachen "Querybuilder" schreiben, aber ich bin es Ich bin mir ziemlich sicher, dass ich nicht der Erste mit dieser Art von Problem bin, daher meine Fragen:

  • Wie erstellt Sie Ihre Datenbankabfragen?
  • Bietet C # eine einfache Möglichkeit zum dynamischen Erstellen von Abfragen?
Ben 15.09.2008, 13:44
quelle

12 Antworten

9

Ich habe C # und Linq verwendet, um etwas Ähnliches zu tun, um Protokolleinträge auf Benutzereingaben zu filtern (siehe Bedingte Linq-Abfragen <) / a>):

%Vor%

Bearbeiten: Die Abfrage wird erst in der letzten Anweisung bis .ToList () ausgeführt.

    
sgwill 15.09.2008, 15:05
quelle
2

Wenn die Ausführungszeit nicht wirklich wichtig ist, würde ich in Betracht ziehen, die Geschäftslogik zu refaktorisieren, die (so oft) ihren Weg in die Datenschicht und in gazillion lange gespeicherte Prozesse findet. Im Hinblick auf Wartungsfreundlichkeit, Editierbarkeit und Anhangfähigkeit versuche ich immer (als C # -Programmierer) den Code bis zum Businesslayer zu heben.

Der Versuch, jemandes 8000-Zeilen-SQL-Skript zu sortieren, ist nicht meine Lieblingsaufgabe.

:)

// W

    
Wiren 15.09.2008 20:18
quelle
1

LINQ ist der richtige Weg.

    
Vinko Vrsalovic 15.09.2008 13:46
quelle
1

So würde ich es machen:

%Vor%

Der Parameter Ausdruck , den Sie übergeben, ist die dynamische Abfrage, die Sie mit den verschiedenen WHERE-Klauseln, JOINS usw. erstellen. Dieser Ausdruck wird zur Laufzeit aufgerufen und dir geben, was du brauchst.

Hier ist ein Beispiel, wie man es nennt:

%Vor%     
Esteban Araya 15.09.2008 15:13
quelle
1

Es ist eine Überlegung wert, wenn Sie eine parametrisierte, gespeicherte Prozedur implementieren und sie in der Datenbank optimieren können, anstatt das SQL dynamisch über LINQ oder ein ORM zur Laufzeit zu generieren. Oft wird dies besser funktionieren. Ich weiß, es ist ein wenig altmodisch, aber manchmal ist es der effektivste Ansatz.

    
rhys 15.09.2008 15:24
quelle
1

Ich verstehe das Potenzial von Linq, aber ich habe noch niemanden gesehen, der versucht, eine Linq-Abfrage der Komplexität zu machen, die Ben vorschlägt

  

die ziemlich komplexe sql-Anweisung (~ 10 Joins, & gt; 10 Subselects, ~ 15-25 wo Bedingungen und GroupBy's)

Hat jemand Beispiele für große Linq-Abfragen und Kommentare zu deren Verwaltbarkeit?

    
Darrel Miller 15.09.2008 23:06
quelle
1

Linq to SQL zusammen mit System.Linq.Dynamic bringt einige nette Möglichkeiten.

Ich habe hier ein paar Beispielcode-Snippets gepostet: Ссылка

... und hier: Ссылка

    
KristoferA 16.09.2008 06:32
quelle
1

Ich komme so spät und habe keine Chance auf eine Verbesserung, aber es gibt eine großartige Lösung, die ich nicht in Betracht gezogen habe: Eine Kombination aus Prozedur / Funktion mit linq-to-object. Oder to-xml oder to-datatable, nehme ich an.

Ich war das in genau dieser Situation, mit einer massiven, dynamisch aufgebauten Abfrage, die eine Art beeindruckende Leistung war, deren Komplexität aber für einen Alptraum sorgte. Ich hatte so viele grüne Kommentare, um den Armen zu helfen, die später mitkommen mussten und es verstanden. Ich war in klassischen Asp, also hatte ich wenige Alternativen.

Was ich seitdem gemacht habe, ist eine Kombination aus function / procedure und linq . Oft ist die Gesamtkomplexität geringer als die Komplexität, es an einer Stelle zu versuchen. Übergeben Sie einige Ihrer Kriterien an die UDF, die viel überschaubarer wird. Dies gibt Ihnen eine überschaubare und verständliche Ergebnismenge. Übernehmen Sie Ihre verbleibenden Auszeichnungen mit linq.

Sie können die Vorteile von beiden nutzen:

  • Verringern Sie die Gesamtzahl der Datensätze so weit wie möglich auf dem Server möglich; bekomme so viele Verrückte Joins auf die gesorgt Server. Datenbanken sind gut Zeug.
  • Linq (zum Objekt usw.) ist nicht so mächtig, eignet sich aber hervorragend zum Ausdruck komplexer Kriterien; Verwenden Sie es also für verschiedene mögliche Unterscheidungen, die dem Code Komplexität hinzufügen, aber dass die db nicht viel besser in der Handhabung wäre. Mit einer reduzierten, normalisierten Ergebnismenge kann linq Complixity ohne große Leistungseinbußen ausdrücken.

Wie entscheidet man, welche Kriterien in der db und welche mit linq gehandhabt werden sollen? Benutze dein Urteil. Wenn Sie komplexe Datenbankabfragen effizient handhaben können, können Sie damit umgehen. Teilkunst, Teilwissenschaft.

    
Patrick Karcher 23.12.2009 19:12
quelle
0

Sie können LINQ oder einen O / R-Mapper wie diesen betrachten: Ссылка

    
Bloodhound 15.09.2008 13:47
quelle
0

Wenn Sie C # und .NET 3.5 verwenden, mit dem Zusatz von MS SQL Server, dann ist LINQ to SQL definitiv der Weg zu gehen. Wenn Sie etwas anderes als diese Kombination verwenden, würde ich eine ORM-Route empfehlen, z. B. nHibernate oder Subsonic .

    
tysonofyork 15.09.2008 15:38
quelle
0

Es gibt eine Art experimenteller Versuch in einer QueryBuilder-Klasse in Ссылка . Könnte einen Blick wert sein.

    
Jonathan Wood 28.01.2011 01:45
quelle
0

Besuche Ссылка . Ich denke, es macht genau das, wonach du suchst.

    
Oleg 09.03.2011 11:55
quelle

Tags und Links