2010-01-27 5 views
6

Sto cercando di trovare il modo ottimale (veloce e semplice) per accedere al codice SQL Server attraverso il codice in C#.Qual è il miglior aproach per ottenere i dati sql da C#

Come stavo imparando dai libri ho incontrato più suggerimenti di solito dicendomi di farlo tramite trascinamento della selezione. Tuttavia, dal momento che volevo farlo in codice, il primo aproach era quello di ottenere i dati per numero di colonna, ma qualsiasi riordino in SQL Query (come l'aggiunta/rimozione di colonne) è stato per me un problema da risolvere.

Per esempio (non ridete, qualche codice è come 2 anni), ho funzione speciale anche codificato per passare sqlQueryResult e verificare se è null o non):

public static void exampleByColumnNumber(string varValue) { 

     string preparedCommand = @"SELECT TOP 1 [SomeColumn],[SomeColumn2] 

            FROM [Database].[dbo].[Table] 
        WHERE [SomeOtherColumn] = @varValue"; 
     SqlCommand sqlQuery = new SqlCommand(preparedCommand, Locale.sqlDataConnection); 
     sqlQuery.Prepare(); 
     sqlQuery.Parameters.AddWithValue("@varValue) ", varValue); 

     SqlDataReader sqlQueryResult = sqlQuery.ExecuteReader(); 
     if (sqlQueryResult != null) { 
      while (sqlQueryResult.Read()) { 
       string var1 = Locale.checkForNullReturnString(sqlQueryResult, 0); 
      string var2 = Locale.checkForNullReturnString(sqlQueryResult, 1); 
      } 
      sqlQueryResult.Close(); 
     } 
    } 

Più tardi ho scoperto è possibile attraverso i nomi delle colonne (che sembra più facile da leggere con più colonne e un sacco di ordine ecc cambiare):

public static void exampleByColumnNames(string varValue) { 

     string preparedCommand = @"SELECT TOP 1 [SomeColumn],[SomeColumn2] 

            FROM [Database].[dbo].[Table] 
        WHERE [SomeOtherColumn] = @varValue"; 
     SqlCommand sqlQuery = new SqlCommand(preparedCommand, Locale.sqlDataConnection); 
     sqlQuery.Prepare(); 
     sqlQuery.Parameters.AddWithValue("@varValue) ", varValue); 

     SqlDataReader sqlQueryResult = sqlQuery.ExecuteReader(); 
     if (sqlQueryResult != null) { 
      while (sqlQueryResult.Read()) { 
       string var1 = (string) sqlQueryResult["SomeColumn"]; 
      string var2 = (string) sqlQueryResult["SomeColumn2"]; 
      } 
      sqlQueryResult.Close(); 
     } 
    } 

e 3 ° esempio è quello di farlo a nomi di colonna, ma utilizzando .ToString() per assicurarsi che sia valore non nullo, o facendo If/else sul controllo null.

public static void exampleByColumnNamesAgain(string varValue) { 

     string preparedCommand = @"SELECT TOP 1 [SomeColumn],[SomeColumn2], [SomeColumn3] 

            FROM [Database].[dbo].[Table] 
        WHERE [SomeOtherColumn] = @varValue"; 
     SqlCommand sqlQuery = new SqlCommand(preparedCommand, Locale.sqlDataConnection); 
     sqlQuery.Prepare(); 
     sqlQuery.Parameters.AddWithValue("@varValue) ", varValue); 

     SqlDataReader sqlQueryResult = sqlQuery.ExecuteReader(); 
     if (sqlQueryResult != null) { 
      while (sqlQueryResult.Read()) { 
       string var1 = (string) sqlQueryResult["SomeColumn"].ToString(); 
      DateTime var2; 
     DateTime.TryParse(sqlQueryResult["SomeColumn2"].ToString()); 

     int varInt = ((int) sqlQueryResult["SomeColumn3"] == null ? 0 : (int) sqlQueryResult["SomeColumn3"]; 

      } 
      sqlQueryResult.Close(); 
     } 
    } 

Si prega di nudo in mente che ho appena creato questa per amore di questo esempio e ci potrebbero essere alcuni errori di battitura o qualche lieve errore di sintassi, ma la questione principale è quale approccio è migliore, che è la peggiore (so che il primo è quello che non mi piace di più).

Presto dovrò iniziare/riscrivere una parte della mia piccola applicazione da 90k linee che ha almeno questi 3 esempi ampiamente utilizzati, quindi mi piacerebbe ottenere il miglior metodo per la velocità e preferibilmente il più facile da mantenere (si spera che sarà stesso aproach).

Probabilmente ci sono alcune opzioni migliori là fuori, quindi per favore condividere?

+1

hai detto 'optimization' precoce? – mjv

+0

Cosa intendi per ottimizzazione prematura? – MadBoy

+1

In generale significa "non preoccuparti delle prestazioni finché non hai finito". Non sai ancora se l'accesso al database sarà il collo di bottiglia, quindi non preoccuparti delle prestazioni in questo momento. Se scrivi codice facile da leggere, facile da capire e facile da gestire, finirai molto più velocemente e con meno errori. Puoi sempre tornare indietro e ottimizzare per le prestazioni in seguito. –

risposta

7

Sembra che tu stia guardando vecchi libri. Se hai intenzione di farlo "alla vecchia maniera", allora dovresti almeno usare i blocchi using. Riassunto:

using (var connection = new SqlConnection(connectionString)) 
{ 
    using (var command = new SqlCommand(commandString, connection)) 
    { 
     using (var reader = command.ExecuteReader()) 
     { 
      // Use the reader 
     } 
    } 
} 

Meglio ancora, guardare in Entity Framework.

vicini: Data Developer Center

+0

La mia domanda era più sull'uso del modo corretto dei nomi delle colonne rispetto ai numeri delle colonne rispetto alle diverse soluzioni. Perché il tuo codice mi ha dato alcuni nuovi suggerimenti che non rispondono completamente alla mia domanda originale :-) – MadBoy

+0

@MadBoy: in realtà, il resto della mia risposta _segue_ la tua domanda. Utilizza Entity Framework e la tua domanda non si pone. Userete semplicemente le proprietà fortemente tipizzate: 'var q = da c nel contesto select c; foreach (var r in q) {// r.SomeColumn; r.SomeColumn2;} ' –

+0

@John Saunders - +1 risposta, ma non c'è bisogno di tutti i nidi' {} '; puoi impilare le linee 'using' e avere un solo livello di nidificazione. In un piccolo esempio non è davvero un problema (altro che una scelta di gusti), ma in un grande blocco di codice può davvero aiutare la leggibilità. – stevehipwell

2

se è facile che stai cercando, non si può fare meglio di LINQ to SQL: -

http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx

Se il database SQL esiste già, puoi essere attivo e funzionante in pochi secondi.

Altrimenti, sono d'accordo con John.

+0

Sì, il database è già attivo e in esecuzione e le persone stanno utilizzando la mia applicazione.Proprio da quando devo continuare lo sviluppo (e migliorarlo nei luoghi in cui sono stato l'anno scorso), so che il codice deve essere pesantemente riscritto in alcuni punti, specialmente perché voglio che sia multithread. – MadBoy

+0

Sarai attivo e funzionante, ma sarai legato alla struttura attuale del tuo database. LINQ to SQL produce sempre un mapping one-to-one tra tabelle e classi del database. Se il tuo database cambia, anche le tue classi dovranno cambiare. Entity Framework risolve questo problema e non si limita a lavorare con SQL Server. –

+0

Assolutamente. D'altra parte, EF ha una curva di apprendimento * molto * più ripida. Sarai attivo e funzionante in pochi minuti anziché in secondi: P –

2

si dovrebbe avere uno sguardo in questi tutorial,

[http://www.asp.net/learn/data-access/][1]

Tutto il lavoro si sta progettando è già stato fatto.

uno sguardo a questo modo di fare la stessa cosa si sta doinng

string preparedCommand = 
    @"SELECT TOP 1 [SomeColumn],[SomeColumn2], [SomeColumn3]  
    FROM [Database].[dbo].[Table] 
    WHERE [SomeOtherColumn] = @varValue"; 
    [1]: http://www.asp.net/learn/data-access/ 

Più modo migliore di fare la stessa di cui sopra è quello di utilizzare LINQ to SQL

var result = from someObject in SomeTable 
      where SomeColumnHasValue == ValueToCompare 
      select new { SomeColumn, SomeColumn1, SomeColumn2}; 
  • No Tipo di sicurezza Numeri
  • Visualizza database in C# mentre si funziona su di esso
  • al momento della compilazione meno errori
  • meno codice
  • più produttivo

seguito sono solo alcuni dei grandi risorse per LINQ, se siete interessati

Speranza che aiuta

+0

Non sai cosa intendi per finirlo e usarlo da solo. L'ho scritto e funziona. Ma dal momento che l'ho scritto e ho imparato C#/sql allo stesso tempo immagino che abbia looooots di codice scadente che prima o poi vorrei sistemare, soprattutto visto che ho bisogno di aggiungere/migliorare qualche codice qua e là in modo da potrei e aggiorna alcune porzioni al codice migliore. – MadBoy

+0

"Presto dovrò iniziare/riscrivere una parte della mia piccola app 90k line che ha ampiamente utilizzato questi 3 esempi", hai ragione, non l'ho capito correttamente, ho pensato, stai per iniziare a lavorare su esso. Comunque. Best Of Luck e spero che ti piaccia lavorare con i nuovi metodi di accesso ai dati mentre sostituisci alcuni dei bit della tua vecchia app. –

+0

modificato la mia risposta. –

1

Se stai cercando in utilizzando ADO.net solo dritto si potrebbe desiderare di uscire e trovare accesso ai dati Application Block di Enterprise Library di Microsoft. David Hayden ha uno decent article che entra in dettaglio sull'utilizzo di esso.

Buona fortuna e spero che questo aiuti alcuni.

1

Il modo più semplice per accedere ai dati in C#, a mio avviso, è l'utilizzo di DataSet digitati. Molto di questo è il drag-and-drop, ed è ancora più semplice con .NET 2.0+ che con .NET 1.0/1.1.

Date un'occhiata a questo articolo, che parla utilizzando DataSet e TableAdapter tipizzati:

Building a DAL using Strongly Typed TableAdapters and DataTables in VS 2005 and ASP.NET 2.0

un DataSet tipizzato è fondamentalmente un contenitore per i dati. Si utilizza un TableAdapter per riempirlo (cosa che accade con SQL o stored proc, a seconda di quello che si preferisce) e per aggiornare i dati in seguito. I nomi delle colonne in ogni DataTable nel DataSet vengono generati automaticamente dall'SQL utilizzato per riempirli; e le relazioni tra le tabelle del database sono riflesse dalle relazioni tra DataTable nel DataSet.

1

Non convertire i dati in stringhe solo per provare ad analizzarli; DataReader hanno metodi per convertire i dati SQL per i tipi di dati .Net:

using (var connection = new SqlConnection(Locale.sqlDataConnection)) 
using (var command = new SqlCommand(preparedCommand, connection)) 
using (var reader = command.ExecuteReader()) 
{ 
    int stringColumnOrdinal = reader.GetOrdinal("SomeColumn"); 
    int dateColumnOrdinal = reader.GetOrdinal("SomeColumn2"); 
    int nullableIntColumnOrdinal = reader.GetOrdinal("SomeColumn3"); 
    while (reader.Read()) 
    { 
     string var1 = reader.GetString(stringColumnOrdinal); 
     DateTime var2 = reader.GetDateTime(dateColumnOrdinal); 
     int? var3 = reader.IsDBNull(nullableIntColumnOrdinal) ? null : (int?)reader.GetInt32(nullableIntColumnOrdinal); 
    } 
} 
+0

Grazie, è utile. – MadBoy

+0

Non puoi avere un numero intero NULL in C#. Dovrebbe essere: int? var3 = reader.IsDBNull (nullableIntColumnOrdinal)? 0: reader.GetInt32 (nullableIntColumnOrdinal); – Switch

+0

@Chizl, non sto creando un intero nullo, sto creando un 'int?'. Non convertire valori nulli a zero, quindi non è possibile distinguere tra un valore mancante/nullo e un valore pari a zero. –

0

ho testare i molti modi diversi per ottenere i dati dal database di SQL Server e ho affrontato & trovato modo più veloce è la seguente:

Prima di tutto creare una classe con il metodo parametrizzato "IDataRecord" secondo le proprietà richieste.

 class emp 
     { 
      public int empid { get; set; } 
      public string name { get; set; } 
      public static emp create(IDataRecord record) 
      { 
       return new emp 
       { 
        empid = Convert.ToInt32(record["Pk_HotelId"]), 
        name = record["HotelName"].ToString() 
       }; 
      } 
     } 

Ora create metodo per ottenere i dati, come di seguito:

public List<S> GetData<S>(string query, Func<IDataRecord, S> selector) 
     { 
      using (var cmd = conn.CreateCommand()) 
      { 
       cmd.CommandText = query; 
       cmd.Connection.Open(); 
       using (var r = cmd.ExecuteReader()) 
       { 
        var items = new List<S>(); 
        while (r.Read()) 
         items.Add(selector(r)); 
        return items; 
       } 
      } 
     } 

e quindi chiamare la funzione come:

var data = GetData<emp>("select * from employeeMaster", emp.create); 
Problemi correlati