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:
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.
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
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%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.
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?
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:
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.
Sie können LINQ oder einen O / R-Mapper wie diesen betrachten: Ссылка
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 .
Es gibt eine Art experimenteller Versuch in einer QueryBuilder-Klasse in Ссылка . Könnte einen Blick wert sein.
Tags und Links sql sql-server c# linq .net-3.5