Was ist der beste Weg, um Daten von einem MS SQL Server in C # abzufragen?
Ich weiß, dass es keine gute Praxis ist, eine SQL-Abfrage im Code zu haben.
Ist der beste Weg, eine gespeicherte Prozedur zu erstellen und sie mit Parametern aus C # aufzurufen?
using (var conn = new SqlConnection(connStr))
using (var command = new SqlCommand("StoredProc", conn) { CommandType = CommandType.StoredProcedure }) {
conn.Open();
command.ExecuteNonQuery();
conn.Close();
}
c#
sql
sql-server
Bruno
quelle
quelle
// SQLCODE
es auch - aber Sie müssen daran denken, das zu tun.Antworten:
Die Verwendung gespeicherter Prozeduren ist eine Möglichkeit und wird seit vielen Jahren häufig verwendet.
Eine modernere Möglichkeit zur Interaktion mit SQL Server-Datenbanken aus C # (oder einer beliebigen .NET-Sprache) ist die Verwendung von Entity Framework. Der Vorteil von Entity Framework besteht darin, dass es eine höhere Abstraktionsebene bietet.
So zitieren Sie von Microsoft ( https://msdn.microsoft.com/en-us/data/jj590134 ):
Mit dem ADO.NET Entity Framework können Entwickler Datenzugriffsanwendungen erstellen, indem sie anhand eines konzeptionellen Anwendungsmodells programmieren, anstatt direkt anhand eines relationalen Speicherschemas zu programmieren. Ziel ist es, den Code- und Wartungsaufwand für datenorientierte Anwendungen zu verringern. Entity Framework-Anwendungen bieten die folgenden Vorteile:
Die Verwendung eines ORM gegenüber gespeicherten Prozeduren beinhaltet Kompromisse, insbesondere in Bezug auf die Sicherheit und wo sich die Logik befindet.
Der "klassische" Ansatz für die Entwicklung mit SQL Server besteht darin, dass sich die Anwendungslogik in gespeicherten Prozeduren und Programmen befindet, denen nur Sicherheitsrechte zum Ausführen gespeicherter Prozeduren erteilt wurden, und keine Tabellen direkt aktualisiert werden. Das Konzept hier ist, dass gespeicherte Prozeduren die Geschäftslogikschicht für die Anwendung (en) sind. Obwohl die Theorie stichhaltig ist, ist sie aus verschiedenen Gründen in Ungnade gefallen und wurde durch die Implementierung der Geschäftslogik in einer Programmiersprache wie C # oder VB ersetzt. Gute Anwendungen werden immer noch mit einem abgestuften Ansatz implementiert, einschließlich der Trennung von Bedenken usw., folgen jedoch eher einem Muster wie MVC.
Ein Nachteil der Implementierung von Logik im ORM anstelle der Datenbank ist das einfache Debuggen und Testen von Datenintegritätsregeln durch die für die Datenbank Verantwortlichen (DA oder DBA). Nehmen wir das klassische Beispiel für die Überweisung von Geld von Ihrem Scheck auf ein Sparkonto. Es ist wichtig, dass dies als atomare Arbeitseinheit erfolgt, dh als Teil einer Transaktion. Wenn diese Art der Übertragung nur über eine gespeicherte Prozedur erfolgen darf, ist es für den Staatsanwalt und die Prüfer relativ einfach, die gespeicherte Prozedur zu überprüfen.
Wenn dies andererseits über ein ORM wie Entity Framework erfolgt und in der Produktion festgestellt wird, dass in seltenen Fällen Geld aus der Prüfung entnommen, aber nicht in das Debuggen von Einsparungen gesteckt wird, kann dies weitaus komplexer sein, insbesondere wenn möglicherweise mehrere Programme beteiligt sind. Dies wäre höchstwahrscheinlich ein Randfall, der möglicherweise besondere Hardwareprobleme mit sich bringt, die in einer bestimmten Reihenfolge auftreten müssen usw. Wie testet man dies?
quelle
Tatsächlich ist die grundlegende Behauptung umstritten - es gibt Kompromisse zwischen SQL im Code oder Code in der Datenbank (wohin Sie mit gespeicherten Prozeduren gehen).
Das Ergebnis ist, dass es kein einziges "Bestes" gibt. Dies können Sie nicht verallgemeinern, da Sie auf jedem Weg einen Kompromiss eingehen (Sie erhalten Vorteile, führen aber auch Einschränkungen ein).
Wenn zwischen Ihrer Anwendung und Ihrer Datenbank eine Eins-zu-Eins-Korrespondenz besteht, spielt dies keine Rolle. Wenn Sie andererseits eine große Kerndatenbank haben, die von einer erheblichen Anzahl von Anwendungen gemeinsam genutzt wird, wird die Durchsetzung der Konsistenz innerhalb der Datenbank zwischen diesen Anwendungen viel wichtiger.
Wichtiger ist es, sich um die Architektur und Schichtung Ihrer Anwendung zu kümmern. Wenn Sie eine geeignete Datenzugriffsschicht verwenden, sollten Sie einen Großteil Ihrer Anwendung von dieser Entscheidung isolieren, unabhängig davon, ob Sie Abfragen erstellen, unabhängig davon, ob Sie Abfragen erstellen oder gespeicherte Prozeduren verwenden.
Ich werde frei daran arbeiten, an relativ kleinen Projekten mit kleinen Teams (1-3 Entwickler) zu arbeiten - die Verwendung gespeicherter Prozeduren ist für mich mehr Mühe als es wert ist, da angesichts der Art unserer Anwendungen (und meiner Fähigkeiten?), Die neu bereitgestellt werden Code ist im Allgemeinen viel einfacher als das Aktualisieren des Schemas (selbst wenn ich Code habe, der das Aktualisieren des Schemas relativ einfach macht), und ich kann Geschäftsregeln mithilfe eines allgemeinen Datenzugriffscodes durchsetzen. Dies ist eindeutig ein klassisches Beispiel für "Ihre Laufleistung kann variieren".
quelle
Solange Sie Ihre Eingaben parametrisiert haben, ist jeder Ansatz gültig. Ein Großteil der Abfragen in Code-Argumenten stammt aus der schlechten alten Zeit, als viele Bibliotheken Sie gezwungen haben, Ihre Anweisungen aneinander zu hängen, und daher kamen SQL-Injection-Angriffe.
quelle
Best Practice ist hier wirklich übertrieben - es gibt viele gute Möglichkeiten, dies zu tun, und die, die Sie auswählen, sollte wirklich davon abhängen, was Ihre App ist und was Sie tun müssen. Das heißt, es gibt nur zwei Dinge, die Sie wirklich falsch machen können:
Wie @Bill hervorhebt, sollten Sie Ihre Abfragen immer parametrisieren. Das Erstellen von Strings ist ein einfacher Vektor für die SQL-Injection sowie für alle Arten von schwer auffindbaren Fehlern. Viel klügere Leute haben herausgefunden, wie man SQL tupelisiert und entkommt, damit Sie es nicht selbst herausfinden müssen.
Schließen Sie Ihre Verbindungen. Der beste Weg ist, alles mit einer using-Anweisung zu verpacken, aber try / catch / finally ist auch cool, wenn das Ihr Boot schwimmt. Aber stellen Sie immer sicher, dass Sie eine Verbindung wie ein billiges Auto verwenden - fahren Sie hart und schnell und entfernen Sie sie schnell.
Die andere Praxis, für die ich vehement argumentieren würde, ist, dass Sie sicherstellen sollten, dass Sie Ihren Datenzugriffscode an so wenigen Stellen wie möglich konzentrieren. Wir erlauben Front-End-Webanwendungen nicht, einen direkten Verweis auf System.Data.SqlClient zu enthalten, um diese Einschränkung durchzusetzen.
quelle