2010-03-16 8 views
6

Sto solo imparando ASP.NET C# e sto cercando di incorporare le migliori pratiche nelle mie applicazioni. Tutto ciò che leggo dice di stratificare le mie applicazioni in DAL, BLL, UI, ecc. In base alla separazione delle preoccupazioni. Invece di passare dati in giro, sto pensando di usare oggetti personalizzati in modo tale che io sia liberamente collegato al mio livello dati e possa sfruttare l'intellisense in VS. Presumo che questi oggetti siano considerati DTO?Come compilare un elenco generico di oggetti in C# dal database SQL

Per prima cosa, dove risiedono questi oggetti nei miei strati? BLL, DAL, altro?

In secondo luogo, quando si esegue il popolamento da SQL, è necessario eseguire il ciclo di un lettore di dati per compilare l'elenco o prima riempire una tabella di dati, quindi eseguire il ciclo della tabella per compilare l'elenco? So che dovresti chiudere la connessione al database il prima possibile, ma sembra che ci sia ancora più overhead per popolare la tabella di dati e poi scorrere per quella lista.

In terzo luogo, tutto ciò che vedo in questi giorni dice usare Linq2SQL. Sto pianificando di imparare Linq2SQL, ma in questo momento sto lavorando con un database precedente che non ha l'installazione di chiavi esterne e non ho la possibilità di ripararlo. Inoltre, voglio saperne di più su C# prima di iniziare a entrare in soluzioni ORM come nHibernate. Allo stesso tempo, non voglio digitare tutta la connessione e l'impianto idraulico SQL per ogni query. È ok usare il DAAB Enterprise per ora?

risposta

17

Hai molte domande in una domanda.

Linq2SQL è solo un tipo di ORM, se si sta andando a quella rotta, guarderei il framework di entità (microsoft's orm).

Parliamo un po 'di applicazioni a più livelli per aiutarti a capire come popolare gli oggetti. La tipica app per database è composta da 3 livelli (alcuni dicono 4 e si riferiscono al database stesso come a un livello, non importa). Sono disponibili le seguenti:

  • UI
  • BLL
  • DAL

Quindi la vostra comunicazione è i colloqui UI al BLL e colloqui BLL al DAL. Il DAL restituisce alcuni dati al BLL che a sua volta lo restituiscono all'interfaccia utente. Non so chi ti ha detto che i set di dati/tabelle sono sbagliati ... certo che un lettore è più veloce, ma non significa che l'uso di un datatable sia sbagliato.

Lasciatemi fare un esempio. Smetti di pensare al tuo DAL come a una classe semplice. Inizia a pensare al livello DAL come a un'intera cartella di classi diverse. Una di queste classi è una classe DB statica. È statico perché hai a che fare con un database (nella maggior parte dei casi), quindi non c'è bisogno di istanziare la classe. Quindi potrebbe essere il seguente:

public static class DB { 
private static readonly string connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString; 
private static readonly DbProviderFactory factory = DbProviderFactories.GetFactory(dataProvider); 

public static int Update(string sql) 
     { 
      using (DbConnection connection = factory.CreateConnection()) 
      { 
       connection.ConnectionString = connectionString; 

       using (DbCommand command = factory.CreateCommand()) 
       { 
        command.Connection = connection; 
        command.CommandText = sql; 

        connection.Open(); 
        return command.ExecuteNonQuery(); 
       } 
      } 
     } 

public static DataTable GetDataTable(string sql) 
     { 
      using (DbConnection connection = factory.CreateConnection()) 
      { 
       connection.ConnectionString = connectionString; 

       using (DbCommand command = factory.CreateCommand()) 
       { 
        command.Connection = connection; 
        command.CommandType = CommandType.Text; 
        command.CommandText = sql; 

        using (DbDataAdapter adapter = factory.CreateDataAdapter()) 
        { 
         adapter.SelectCommand = command; 

         DataTable dt = new DataTable(); 
         adapter.Fill(dt); 

         return dt; 
        } 
       } 
      } 
} 

Alcuni di questi sono stati presi dal sito Web di dofactory. Grande risorsa per imparare come utilizzare i modelli di progettazione. Comunque è solo un file .class. Ora ne hai bisogno di un altro per dire un CustomerDAO (un oggetto di accesso ai dati del cliente).

Ok, quindi come si può usare quella classe DB che hai creato (beh, io userei una combinazione di sproc, ma per fare in modo che questo semplice post consenta di evitare le stored procedure per ora). Se ho bisogno di ottenere i clienti che potrei definire questo:

public IList<Customer> GetCustomers() 
{ 
    StringBuilder sql = new StringBuilder(); 
    sql.Append(" SELECT CustomerId, CompanyName, City, Country "); 
    sql.Append(" FROM Customer "); 

    DataTable dt = Db.GetDataTable(sql.ToString()); 

    return MakeCustomers(dt); 
} 

ricordate che questo è in un file .class completamente diverso.Ok, quindi, come fa sembrare i clienti:

private IList<Customer> MakeCustomers(DataTable dt) 
     { 
      IList<Customer> list = new List<Customer>(); 
      foreach (DataRow row in dt.Rows) 
       list.Add(MakeCustomer(row)); 

      return list; 
     } 

Quindi quello che sto facendo qui è che avevo un datatable pieno di clienti. Ho bisogno di un ciclo tra ogni riga del DataTable e rendere il cliente:

private Customer MakeCustomer(DataRow row) 
     { 
      int customerId = int.Parse(row["CustomerId"].ToString()); 
      string company = row["CompanyName"].ToString(); 
      string city = row["City"].ToString(); 
      string country = row["Country"].ToString(); 

      return new Customer(customerId, company, city, country); 
     } 

Quindi questo cliente è new'd e conservato in un elenco di clienti.

Questo è solo un piccolo esempio di ciò che fa il vostro Data Access Layer. La classe di database memorizza semplicemente la stringa di connessione e le funzioni per ottenere un set di dati o ottenere una tabella di dati o anche nel tuo caso ottenere un lettore di dati (cosa che potresti fare anche tu). La classe CustomerDAO è semplicemente una classe che si occupa di oggetti del cliente e può implementare un'interfaccia ICustomer.

Quindi, dov'è la classe Cliente stessa? Può essere in un'altra cartella come livello aziendale, perché è semplicemente un oggetto aziendale. Qui puoi impostare convalide e campi obbligatori all'interno della classe cliente.

L'interfaccia utente non ha nulla correlato a datareader, dataset o SQL. Il tuo livello aziendale non ha nulla a che fare con esso (definisce alcune regole dietro i tuoi oggetti di business). Il tuo può essere molto flessibile (può funzionare con SQL, Oracle, ecc.) O può essere limitato a dire SQL Server se questo è ciò che pensi di fare. Non sovraccaricare la tua app. Se sei un ragazzo di MS e sei sicuro di utilizzare solo SQL Server, non rendi il tuo lavoro difficile cercando di implementare il DAL definitivo che funziona con qualsiasi fornitore. è corretto usare SQLCommand, SQLConnection, ecc.

+0

Perché non combinare solo ottenere clienti, clienti, clienti in un unico metodo? – jpshook

+0

@developr - Allora avresti una brutta funzione. È necessario separare le preoccupazioni in modo da non complicare una funzione. Una funzione dovrebbe semplicemente fare * un * lavoro/compito. Se lo metto tutto in uno, otterresti clienti, oltre a recuperare/loop-through dei clienti, oltre a creare nuovi clienti allocando spazio, oltre a assegnare valori all'oggetto cliente e infine aggiungere il cliente all'elenco. Potresti fare tutto in uno ma complica la tua funzione. Anche la leggibilità è molto più semplice nel mio esempio. – JonH

+0

Come aggiungerei parametri al metodo Update nella classe DB nel modo corretto? Non suppongo, ti piacerebbe: DB.Update ("tabella di aggiornamento set username = '" + varusername + "' WHERE x =" + varx + "); ... così passeresti un SqlCommand con parametri o dizionario o chiave/elenco di valori e costruire lo sqlcommand nel metodo di aggiornamento.Sto pensando che l'usabilità del metodo dovrebbe essere il più ampia/generale possibile. – Jesper

0

Vai a controllare l'ORM OpenAccess di Telerik. Non devi usarlo come "ORM" ma ti darà la possibilità di generare rapidamente classi per le tue tabelle senza doverle digitare tutte. Quindi puoi utilizzare queste classi con caratteri forti nel tuo DAL per tutto ciò che vuoi, sia che sia personalizzato o basato su ORM con qualcos'altro. In questo caso, lo stai solo usando per la generazione del codice per farti iniziare velocemente (e questi oggetti sono molto semplici e di base - cioè esattamente dove avresti iniziato se dovessi scriverli a mano).

Per quanto riguarda l'astrazione degli oggetti DAL dagli altri oggetti, consultare WCF. Puoi metterlo tra ogni livello (UI/Biz/DAL) e genererà oggetti proxy che si prenderanno cura della tua separazione di preoccupazioni.

Problemi correlati