Connessione a database

di il
14 risposte

Connessione a database

Salve a tutti, in una applicazione che stò scrivendo, faccio uso di un database.
La stringa di connessione che ho sempre utilizzato è :
string connectionstring = @"Data Source = (LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\Gianl\source\repos\DBManager\DBManager\Database1.mdf;Integrated Security = True";
Successivamente ho voluto provare a spostare il file del database su un unità di rete e quindi la stringa di connessione è diventata:
string connectionstring = @"Data Source = (LocalDB)\MSSQLLocalDB;AttachDbFilename=\\192.168.1.1\volume(sda)\Database1.mdf;Integrated Security = True"; 
La cosa sembrava funzionare, fino a quando non ho provato ad utilizzare l'applicazione su 2 pc diversi, quando l'applicazione su un pc accede al database, sull'applicazione dell'altro pc non riesco a connettermi al database, ovvero quando si tenta la connessione esce un errore.
In pratica posso utilizzare l'applicazione su un pc alla volta, quando l'applicazione sull'altro pc si avvia, e quindi deve accedere al database per scaricare i dati, esce l'errore, "il server non è stato trovato o non è accessibile"

Evidentemente mi sfugge qualcosa per poter far accedere i 2 pc contemporaneamente allo stesso database.

Qualcuno può darmi una mano a risolvere il problema....
Grazie.

14 Risposte

  • Re: Connessione a database

    "only one LocalDB instance can have any given database file open at the same time"

    Usa una versione Exptess installata e configurata su un terzo pc (o su uno dei due) come server
  • Re: Connessione a database

    Grazie per la risposta, in realtà non è ben capito cosa mi stai proponendo, ma forse ho capito che in quel modo, servono tutti i pc accesi contemporaneamente, che è proprio la cosa che vorrei evitare.
    Ho la possibilità di condividere file tra più pc tramite archivio di rete, proprio per evitare di dover tenere accesi entrambi i pc.
    Poi ovvio che può succedere di dover lavorare con la stessa applicazione contemporaneamente su più pc, e vorrei che la cosa funzionasse.
  • Re: Connessione a database

    No ... che c'entra? Devi accendere il pc dove installi il DBMS 3 ovviamente quelli che si collegano al DB ma è ovvio e non vedo quale sia il problema.
    La questione è che se vuoi accedere contemporaneamente da più pc al db non puoi usare il localdb
  • Re: Connessione a database

    Si, infatti chiedevo cosa devo utilizzare invece di local db.
    Mi serve un server dove c'è da installare un database, o esiste un modo per utilizzare file mdf e ldf del database?
  • Re: Connessione a database

    GianlucaB ha scritto:


    Si, infatti chiedevo cosa devo utilizzare invece di local db.
    Ti è stato detto: devi installare un SQL Server edizione Express o superiore.

    GianlucaB ha scritto:


    Mi serve un server dove c'è da installare un database, o esiste un modo per utilizzare file mdf e ldf del database?
    Il formato LocalDB è utile per applicazioni "embedded": per l'accesso simultaneo da parte di più applicazioni, occorre un server.

    Ciao!
  • Re: Connessione a database

    Sono rimasto fregato, dai file mdf, perché pensavo che una volta connesso, scaricato i dati, e disconnesso, il file rimanesse libero, per altre connessioni da parte di altre applicazioni.
    Se il file deve rimanere comunque in uso, allora tutto il lavoro fatto per scaricare in locale i dati, non mi serve a nulla, come a questo punto non capisco nemmeno l'istruzione Close, o ClearPool, a cosa serve chiudere e disconnettere, se poi il file rimane comunque in uso?
  • Re: Connessione a database

    GianlucaB ha scritto:


    Sono rimasto fregato, dai file mdf, perché pensavo che una volta connesso, scaricato i dati, e disconnesso, il file rimanesse libero, per altre connessioni da parte di altre applicazioni.
    Se il file deve rimanere comunque in uso, allora tutto il lavoro fatto per scaricare in locale i dati, non mi serve a nulla, come a questo punto non capisco nemmeno l'istruzione Close, o ClearPool, a cosa serve chiudere e disconnettere, se poi il file rimane comunque in uso?
    Se il file del database viene chiuso, altre applicazioni in locale possono connettersi.
    Se non puoi controllare che solo un'applicazione alla volta si colleghi, allora l'uso del LocalDB non è possibile.
  • Re: Connessione a database

    Abbiate pazienza, ma continua a sfuggirmi qualcosa.

    L'applicazione è stata scritta, in modo che faccio connessioni al database solo quando serve.
    All'avvio mi connetto al database, scarico i dati in locale, e chiudo la connessione con il database.
    A quel punto l'applicazione può lavorare anche senza più il database, tutti i dati stanno dentro a dei datatable in locale.
    Solo se c'è da modificare dei record, allora mi riconnetto al database, eseguo la query e mi disconnetto.

    Praticamente le connessioni al database sono rare, e durano frazioni di secondo, l'applicazione è stata scritta appositamente per non stare continuamente connessa con il database.

    Così facendo, credevo di poter tenere liberi i file del database, o meglio occuparli solo per quelle frazioni di secondo, in cui è necessario eseguire una query.


    Invece pare che non sia così, i file del database, permangono sempre in uso da SQL Server, anche dopo aver chiuso la connessione con il comando close, e aver cancellato la connessione con il comando ClearPool o anche ClearAllPools

    Se ad esempio provo a fare un copia incolla del file database, quando l'applicazione è aperta, mi esce che il file è aperto in SQL Server.

    Quindi continuo a non capire a cosa serve chiudere connessioni, e cancellare connessioni con il database, se poi comunque mi rimane sempre in uso?
  • Re: Connessione a database

    GianlucaB ha scritto:


    Quindi continuo a non capire a cosa serve chiudere connessioni, e cancellare connessioni con il database, se poi comunque mi rimane sempre in uso?
    Ma tu sei davvero sicuro di chiudere correttamente la connessione al database?

    Senza vedere niente del codice, si possono fare solo supposizioni.

    Tra l'altro, non avendo da gestire un pool di connessioni (date tutte le premesse) non è chiaro perché tu vada a chiamare un metodo come ClearAllPools(), visto che un pool non ci sarà mai su un database che accetta una e una sola connessione.

    Mi sembra che tu stia tentando il tutto per tutto invocando dei metodi che non hanno senso, e che magari sono proprio quelli a riprodurre il problema.

    Prova a postare la parte di codice significativa interessata dal problema o rappresentativa del modo che usi per aprire, usare e infine chiudere la connessione.

    Ciao!
  • Re: Connessione a database

    Dunque, per togliere ogni dubbio ho creato una nuova applicazione di test con una parte di codice interessata.
    
    namespace ConnectionTest
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            public void CostUpdate(string _Cost, int _id)
            {
                string connectionstring = @"Data Source = (LocalDB)\MSSQLLocalDB;AttachDbFilename=\\192.168.1.1\volume(sda)\Database1.mdf;Integrated Security = True";
    
                SqlConnection conn = new SqlConnection(connectionstring);
    
                conn.Open();
                SqlCommand comando = new SqlCommand("", conn);
              
                comando.CommandText = "UPDATE Product SET Cost='" + _Cost + "' where id=" + _id;
                comando.ExecuteNonQuery();
    
                conn.Close();
    
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                int id = 5880;
                string cost = "1";
                CostUpdate(cost,id);
            }
        }
        
    }
    
    L'applicazione è composta da un pulsante, quando viene premuto apro la connessione al database, faccio un update di un record, e chiudo la connessione con il comando conn.Close()

    Fino a quando non premo il button, il file del database è libero e accessibile, anche con l'applicazione già avviata.
    Appena clicco sul button1 ed eseguo l'update, il file mdf del database diventa in uso a SQL server, e così rimane fino a quando non chiudo l'applicazione.

    Quindi devo supporre che il comando conn.Close() non stà avendo l'effetto sperato?
  • Re: Connessione a database

    GianlucaB ha scritto:


    Dunque, per togliere ogni dubbio ho creato una nuova applicazione di test.
    Il codice sembra corretto. Nel frattempo, dando un'occhiata in giro, ho trovato questo articolo che descrive parte del funzionamento di LocalDB.

    Pare che l'apertura della connessione faccia partire il processo esterno di LocalDB; questo processo gestisce il file del database. Nel momento in cui chiudi la connessione, questa viene effettivamente chiusa ma il processo rimane attivo e tiene bloccato il file, chiudendosi (ipoteticamente, stando a quello che c'è scritto) dopo pochi istanti.

    In breve, non è comunque la tua applicazione che apre e tiene bloccato il file, ma esiste comunque un processo dedicato.

    Per forzare lo sgancio, ci sembrano essere diversi metodi, tipo questo qui: in breve, si fa il DETACH del database.

    Essendo rivolto a sviluppatori e trovando la propria utilità in demo e altre applicazioni affini, fossi in te opterei per spostarti verso SQL Server oppure verso un database realmente "file based", tipo SQLite.

    Ciao!
  • Re: Connessione a database

    Ottimo, bastato aggiungere questi 2 comandi
    
    comando.CommandText = String.Format("ALTER DATABASE [{0}] SET OFFLINE WITH ROLLBACK IMMEDIATE", @"\\192.168.1.1\volume(sda)\Database1.mdf");
                comando.ExecuteNonQuery();
    
                comando.CommandText = String.Format("exec sp_detach_db '{0}'", @"\\192.168.1.1\volume(sda)\Database1.mdf");
                comando.ExecuteNonQuery();
    
    
    In realtà provando basta pure solo il primo comando, che mette offline il database, ed il file torna accessibile.

    A questo punto dato che le connessioni durano frazioni di secondo, e il timeout di connessione è di 30 secondi, anche in caso di più applicazioni che accedono contemporaneamente al database, credo di non avere problemi.

    Teoricamente l'applicazione che trova il database occupato, può aspettare fino 30 secondi, tempo più che sufficiente per permettere all'altra applicazione che stà usando il database di liberarlo, dato che l'operazione sul database dura una frazione di secondo.


    Grazie a tutti per l'aiuto.
  • Re: Connessione a database

    GianlucaB ha scritto:


    Ottimo, bastato aggiungere questi 2 comandi [...]
    Considerando che stai usando un database che non è propriamente adatto agli scopi, che lo stai aprendo via rete (facendo viaggiare inutilmente tutti i dati attraverso la LAN), che devi per forza eseguire operazioni di "detach" per sganciarlo, che altri applicativi potrebbero stare in attesa, mi sembra una soluzione molto pericolante.

    Prega che i dati rimangano sempre contenuti, altrimenti prevedo la necessità di mettere mano quanto prima alla baracca, perché di certo così non è molto scalabile e forse contravviene anche alla licenza d'uso.

    Però, detto questo, se sei contento tu...
  • Re: Connessione a database

    Si certo concordo con te, non è assolutamente una soluzione professionale, ma mi permette di condividere un database tra più pc, senza dover per forza utilizzare un server.
    Alla fine stiamo parlando di una cosa personale, che uso io in casa mia, nella mia rete locale e basta, quindi non credo di contravvenire a nessuna licenza d'uso.
Devi accedere o registrarti per scrivere nel forum
14 risposte