2009-06-15 12 views
0

nehme an, Sie haben ein paar einfache sprocs zBAufruf sprocs von einer DB-Schicht in C#

AddXYZ (param1, param 2 ... etc)

getAllXYZ()

getXYZ (id)

Was ist der "Best Practice" Weg, diese Sprocs von der "db Schicht" aufzurufen

ich möchte nicht linq verwenden. nur einfache C# statische Methoden, um dies zu tun.

im Verwendung sqlserver.

Antwort

5

Ist das wonach Sie suchen?

SqlCommand cmd = new SqlCommand("AddXYZ", conn); 
cmd.CommandType = CommandType.StoredProcedure; 
cmd.Parameters.Add(new SqlParameter("@param1", someValue)); 
0

Im Allgemeinen dann, werden Sie an der SQLConnection und SQLCommand Klassen suchen möchten (vorausgesetzt, Sie zu einer SQL db sich verbinden, natürlich). Sie setzen die SQLCommand.CommandText -Eigenschaft auf etwas wie "EXEC AddXYZ @X, @Y, @Z" und verwenden dann SQLCommand.Parameters.AddWithValue() für jedes von @X, @Y und @Z.

Anschließend rufen Sie die entsprechende Ausführungsmethode Ihres SQLCommand (NonQuery, Scalar oder Reader) auf.

8

Ich glaube nicht, dass Sie wirklich static Methoden meinten, wie das wäre eine ziemlich non-OO Art und Weise von so etwas zu tun, und keine solche Einrichtung ist in C# eingebaut. Es gibt jedoch Standard-ADO.NET-Klassen, die Sie ohne ORM-Wrapping oder DataSet und dergleichen verwenden können.

Wenn Sie wirklich den gespeicherten Proc manuell aufrufen und eine Reihe von abrufen möchten Ergebnisse ohne es für Sie jede ORM oder standardisierte Speichermechanismus zu tun, dies die beste Wahl wäre:

using(System.Data.IDbConnection conn = /*create your connection here*/) 
{ 
    using(System.Data.IDbCommand cmd = conn.CreateCommand()) 
    { 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.CommandText = "AddXYZ"; 

     // add your parameters here using cmd.CreateParameter() and cmd.Parameters.Add() 

     using(System.Data.IDbDataReader reader = cmd.ExecuteReader()) 
     { 
      while(reader.Read()) 
      { 
       // read your results row-by-row 
      } 
     } 
    } 
} 

Sie nicht angeben, welche Datenbank-Engine Sie wurden durch Verbinden, so habe ich die gemeinsamen Schnittstellen, wird abstrakt Sie davon entfernt. Wenn Sie möchten (obwohl ich generell den Code missbrauche, der das tut), können Sie plattformspezifische Klassen verwenden, die die Dinge LEICHT erleichtern, zumindest was das Hinzufügen von Parametern betrifft (der Code ist nicht so ausführlich wie der interface-basierte Ansatz)

+0

tut mir leid im using sqlserver. – raklos

+0

+1 für 'using()', um Speicherlecks zu beseitigen! –

+3

es ist nicht Speicher, um den Sie sich sorgen müssen - es sind die Db-Verbindungen. –

1

Zunächst erstellen Sie eine einzelne Stelle in der Datenschicht, um Verbindungsinformationen abzurufen. Dies kann ein privates Mitglied sein, wenn Ihre Datenschicht auf eine einzelne Klasse oder ein internes Element beschränkt ist, wenn die Ebene eine gesamte Baugruppe umfasst. Es könnte eine Verbindungszeichenfolge oder ein tatsächliches Verbindungsobjekt zurückgeben selbst, aber die Hauptsache ist, dass es überhaupt nicht außerhalb der Datenschicht ausgesetzt ist:

private static ConnectionString { get { // read from config file once.... return ""; } } 

private SqlConnection getConnection() 
{ 
    SqlConnection result = new SqlConnection(ConnectionString); 
    result.Open(); // I like to open it in advance, but that's less common 
    return result; // you'll want some error handling code in here as well 
} 

Sie dann öffentliche Methoden in der Datenschicht bereitzustellen, die die Schnittstelle, die Sie passen möchte der Business-Schicht zur Verfügung stellen. In einer gut gestalteten App wird dies im Allgemeinen mit den gespeicherten Prozeduren übereinstimmen, und das hört sich nach dem an, was Sie anstreben, aber manchmal klappt es nicht so gut. Sie müssen möglicherweise mehrere Prozeduren von einer Methode aufrufen.

Was auch immer Sie tun, die Methode sollte stark typisierte Parameterwerte akzeptieren, die beim Aufrufen der Prozeduren verwendet werden. Es gibt Diskussionen darüber, ob die Methode ein Geschäftsobjekt oder einen Datensatz zurückgeben soll.Persönlich neige ich Zurückgeben eines Datarecord favorisieren, sondern eine zusätzliche „Schicht“ ermöglichen, wenn die data übersetzt werden stark typisierte Business-Objekte:

public IDataRecord GetXYZ(int id) 
{ 
    DataTable dt = new DataTable(); 
    using (var cn = getConnection()) 
    using (var cmd = new SqlCommand("getXYZ")) 
    { 
     cmd.CommandType = CommandTypes.StoredProcedure; 
     cmd.Parameters.Add("@ID", SqlDbType.Int).Value = id; 

     using (var rdr = cmd.ExecuteReader()) 
     { 
      dt.Load(rdr); 
     } 
    } 

    //obviously put a little more work into your error handling 
    if (dt.Rows.Count <= 0) 
     throw new Exception("oops"); 

    return dt.Rows[0]; 
} 

public class XYZFactory 
{ 
    public static XZY Create(IDataRecord row) 
    { 
     XYZ result = new XYZ(); 
     result.id = row["ID"]; 
     result.otherfield = row["otherfield"]; 
     return result; 
    } 
} 
0

Thomas' Beispiel der normale Weg ist. Ich schlage vor, Sie sehen Sie die folgenden für weitere Hilfe:

http://msdn.microsoft.com/en-us/library/aa902662.aspx

Ich persönlich habe eine statische Klasse geschrieben (DataHelper), die eine Reihe von Methoden aussetzt, die Sie wahrscheinlich sind, wie jene zu verwenden, die Rückkehr IDataReader-Objekte für den Fall, dass Ihr gespeicherter Prozess Daten zurückgibt, und ungültige Methoden für den Fall, dass dies nicht der Fall ist, sowie für einige, die das Connection-Objekt in einem out-Parameter zurückgeben, damit Sie es geöffnet halten können.

Die Klasse umschließt den ADO.NET-Code nur in try-catch-Blöcken für die allgemeine Problemprüfung und -protokollierung (DNS down, Server down, svc down) und verwendet die using-Anweisung, um sicherzustellen, dass Ressourcen nicht verschwendet werden. Ich umschließe auch eine Methode, die ConnectionStringBuilder verwendet, um eine Verbindungszeichenfolge zurückzugeben, damit ich diesen Code nicht weiter schreiben muss.

Ich fand, dass für ein großes Projekt, Kodierung alle meine Entität "Anbieter" wiederholt wurde und ich hätte ein mehr wiederverwendbares Konfigurationsmodell entwickelt.

In diesen Tagen, wenn ich Greenfield hatte, würde ich mit dem EDM betrachten.

http://msdn.microsoft.com/en-us/library/aa697428(VS.80).aspx