3 messaggi dal 31 luglio 2017
Ciao a tutti, premesso che sto iniziando da poco a programmare in c#, volevo realizzare un collegamento dinamico che mi permettesse di cambiare database ogni volta che ne avevo bisogno senza dover riscrivere parte di codice e ci sono riuscito.
Ho fatto in questo modo:
public partial class Form1 : Form
{

OleDbConnection kon = new OleDbConnection(@"File Name = c:\DBDEMOS.udl");
public OleDbConnection MyDataB { get => kon; set => kon = value; }

public static string nomeDB;
//
private void Form1_Load(object sender, EventArgs e)
{
try
{
MyDataB.Open();

OleDbCommand kcon = MyDataB.CreateCommand();
kcon.CommandType = CommandType.Text;
kcon.CommandText = "SELECT NOME, DIRECTORY, ATTIVO FROM Dati WHERE ATTIVO=-1";
OleDbDataReader leggiDb;

leggiDb = kcon.ExecuteReader();

leggiDb.Read();
nomeDB = Convert.ToString(leggiDb["NOME"]);

leggiDb.Close();
}
catch (Exception)
{
MyDataB.Dispose();
MyDataB.Close();
}
finally
{
MyDataB.Dispose();
MyDataB.Close();
}

//
string connectionString = string.Format("Provider={0}; Data Source=C:\\MioProgramma\\{1}; Jet OLEDB:Engine Type={2}", "Microsoft.Jet.OLEDB.4.0", Form1.nomeDB, 5);
OleDbConnection con = new OleDbConnection(connectionString);
//
Inizialmente volevo modificare in runtime il file udl cambiando il nome del datbase, ma ho scoperto che e' necessario Microsoft Data Link per riscriverlo. Comunque, vado a leggere un archivio dove ho inserito i miei database o vado a selezionare il database su cui lavorare. Funziona! Vorrei pero' riassumere tutto in un file di classe, e qui ho un po' di problemi. Qualcuno mi puo' aiutare? Grazie!
Modificato da devel il 31 luglio 2017 13.41 -
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao e benvenuto nel forum!
Spiega che cosa hai provato a fare e le difficoltà che hai incontrato.

Tipicamente, le classi che si occupano di recuperare delle informazioni dal database prendono il nome di Repository, ma non è ovviamente obbligatorio chiamarle così.

La classe repository, che si occuperà materialmente di inviare una query al database usando il codice che hai scritto, potrà anche restituire al chiamante una lista di oggetti in cui saranno state riversate le informazioni lette grazie all'OleDbDataReader.

Quindi, per prima cosa, creiamo una classe per questi oggetti che contenga le proprietà Nome, Directory e Attivo, in cui verranno copiati i valori ottenuti dal db. Come la vogliamo chiamare? "Dati" non è molto significativo. Dovresti scegliere un nome che spieghi bene cosa rappresentano quei tre valori Nome, Directory e Attivo. Diciamo che sono "utenti", dove Nome rappresenta il nome dell'utente; Directory la sua cartella home e Attivo se è ancora un utente valido o no. Ovviamente io qui sto tirando ad indovinare, dovrai scegliere tu un nome significativo per questa classe.

public class Utente {
  public string Nome { get; set; }
  public string Directory { get; set; }
  public bool Attivo { get; set; }
}


Questa classe servirà ad isolare il mondo relazionale (dei database) da quello orientato agli oggetti. Il ruolo della tua classe repository sarà appunto quello di evitare che la logica di accesso al database sia spalmata un po' in tutto il progetto. Questa classe si occuperà di fornire liste di oggetti Utente, lasciando il resto dell'applicazione allo scuro di come siano stati ottenuti (è una cosa positiva, perché così non dovranno interessarsi anche loro di quei dettagli implementativi).

Questa sarà (approssimativamente) la classe repository.
public class RepositoryUtenti {

  //Nel costruttore accettiamo la connection string, così che questa classe
  //possa funzionare con vari database (purché abbiano la stessa struttura)
  private string connectionString;
  public RepositoryUtenti(string connectionString) {
    this.connectionString = connectionString;
  }

  //Ora creiamo il metodo che estrae gli utenti dal database
  public IEnumerable<Utente> EstraiUtenti() {
    //Il blocco using mi assicura che la connessione e il comando vengano
    //distrutti al termine del loro utilizzo, anche se si dovesse verificare un'eccezione
    using (var myDataB = new OleDbConnection(connectionString)) {
      myDataB.Open(); 
      using (var kcon = myDataB.CreateCommand()) {
        kcon.CommandText = "SELECT NOME, DIRECTORY, ATTIVO FROM Dati WHERE ATTIVO=-1";
      using (var leggiDb = kcon.ExecuteReader()) {
        while (leggiDb.Read()) {
          //Per ogni risultato, creo un'istanza della classe Utente
            //copiandoci dentro i valori letti dal database.
          //Con il yield return restituisco uno ad uno tutti gli utenti
          yield return new Utente {
            Nome = (string) leggiDb["NOME"],
            Directory = (string) leggiDb["DIRECTORY"],
            Attivo = (int) leggiDb["ATTIVO"] == -1
          };
          }
        }
      }
    }
  }
}


La potrai usare così dal tuo form:
var repo = new RepositoryUtenti(@"File Name = c:\DBDEMOS.udl");
var utenti = repo.EstraiUtenti().ToList();
//Ora puoi fare quello che vuoi con la tua lista di utenti. Per esempio ciclarli.
foreach (Utente utente in utenti) {
  //fai qualcosa con utente
} 


ciao,
Moreno
Modificato da BrightSoul il 31 luglio 2017 21.59 -

Enjoy learning and just keep making
3 messaggi dal 31 luglio 2017
Ciao e ben trovati, grazie per la risposta adatterò il tutto alle mie esigenze e approfondirò di più le Repository.
Comunque quello che ho cercato di realizzare, era fare una procedura che mi permettesse di avere più database o ditte in modo da poterle richiamare a seconda dell'esigenza (tipo programma multi aziendale, in cui si può scegliere l'azienda dove lavorare).
l'ho pensata in questo modo:
Un primo collegamento leggeva il database evidenziato nell'archivio Dati o Aziende, e assegnando il valore restituito ad una variabile globale (nomeDB), poi con la seguente riga mi collegavo all'archivio desiderato:

string connectionString = string.Format("Provider={0}; Data Source=C:\\MioProgramma\\{1}; Jet OLEDB:Engine Type={2}", "Microsoft.Jet.OLEDB.4.0", nomeDB, 5);

C'è un modo migliore per poter fare una cosa del genere oppure va bene come ho pensato?
Grazie di nuovo e ciao

Nino
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao Nino,
puoi fare in modo che quando l'utente fa il login, vai a determinare da quale database deve pescare. Quando l'hai determinato, inserisci questa informazione nel cookie di autenticazione. Il cookie ti verrà restituito ad ogni successiva richiesta dell'utente e tu saprai a quale db devi collegarti senza fare ulteriori richieste al database. E' questa la tua "variabile globale".

Con questa informazione, componi la connection string come hai mostrato tu e passala al costruttore di RepositoryUtenti.

Qui trovi un esempio di codice per produrre il cookie di autenticazione contenente delle informazioni aggiuntive (denominate "claims").
https://forums.asp.net/t/2059892.aspx?Attaching+Claims+to+the+FormsIdentity+in+ASP+NET+MVC

ciao,
Moreno

Enjoy learning and just keep making
3 messaggi dal 31 luglio 2017
Grazie Moreno.
Ciao
Nino
Modificato da devel il 02 agosto 2017 00.10 -

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.