Per le domande 1 e 2 vai con le risposte di Matteo.
Ho impiegato molto tempo a cercare di capire il modo migliore per strutturare il DAL delle applicazioni desktop. E il modo migliore dipende in realtà dalle esigenze dell'applicazione. In una delle mie app mi sono imbattuto in una classe DA per ogni tabella di database, che si è registrata con una classe DataProvider centrale (cioè singleton) e ha gestito il CRUD. Ciascuna classe DA può quindi decidere se desidera memorizzare nella cache tutti i dati della tabella nella RAM o meno (prestazioni!) E / o se è necessario avere la capacità di attivare gli aggiornamenti automatici dei client in altri client in esecuzione su altri computer (si pensi multiutente concorrenza). Ciò semplifica l'aggiunta di nuove classi DAL, poiché tutto ciò che devono fare è conformarsi all'interfaccia di registrazione.
Non tutti i DAL hanno bisogno di questo tipo di funzionalità, ma ho appreso che l'approccio stesso (cioè fornitore di dati singleton e semplici classi DAL con registrazione statica) mi ha reso la vita molto più semplice quando ho iniziato ad aggiungere nuove classi.
Non raccomanderei assolutamente di costruire il CRUD nelle classi di livello superiore, a meno che non si tratti di un'applicazione molto semplice. Il DAL è un'astrazione della memorizzazione dei dati. Se decidi di cambiare l'archiviazione dei dati in futuro (anche se è solo per usare MySQL invece di MS SQL), sarai molto grato per questo. Inoltre: gli oggetti BLL dovrebbero essere strutturati in base alle loro relazioni logiche di business. Gli oggetti DAL sono strutturati dai tipi di contenitori di memoria che rappresentano. Le differenze possono essere drammatiche.
Fai NON rendere statiche le tue classi DAL. Ciò che guadagni in velocità di codifica perderà molte volte in testabilità e flessibilità.