giovedì 5 novembre 2015

ADOX Class con c# e la versione a 32 bit per creare un database Access mdb

Dopo svariati tentativi sono riuscito ad utilizzare un provider buono che girasse su server a 64bit senza cambiare l'opzione su IIS per "Enable 32-Bit Applications".
Creare tramite codice c# su un applicativo web in .Net un database Access mdb e collegare delle tabelle all'interno non è stata una passeggiata.
Per utilizzare la connessione con Jet.OLEDB bisognava avere per forza questa abilitazione.
Ecco l'errore che usciva su sistema a 64bit:
System.Runtime.InteropServices.COMException (0x80040154): Class not registered at ADOX.CatalogClass.Create

Poi mi sono inbattuto su questo link:
https://social.msdn.microsoft.com/Forums/en-US/1d5c04c7-157f-4955-a14b-41d912d50a64/how-to-fix-error-the-microsoftaceoledb120-provider-is-not-registered-on-the-local-machine?forum=vstsdb
e ho provato a scaricare il motore 2010. Niente da fare ecco l'errore:
"the 'microsoft.ace.oledb.12.0' provider is not registered on the local machine"

Ho scaricato infine l'engine 2007 alla seconda opzione qui
Incredulo e increduli... ha funzionato!
Ovviamente sul server non avevo installato il pacchetto Office, quindi è risultato semplice installare questo pacchetto Microsoft gratuito, che mi ha permesso di creare un database Access e creare all'interno anche tabelle collegate.
Di seguito un esempio di codice che ho utilizzato:

string tFilePath = "c:\example.mdb";
// string MDBConnStr = "Provider=Microsoft.Jet.OLEDB.4.0; data source=" + tFilePath + ";Jet OLEDB:Engine Type=5";

// REPLACE WITH THIS
string MDBConnStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + tFilePath + ";";

ADOX.CatalogClass tCat = new ADOX.CatalogClass();
ADODB.Connection conAdodb=null;
try
{
 tCat.Create(MDBConnStr);
 conAdodb = (ADODB.Connection)tCat.ActiveConnection;
 
 //..code here, create table, linked table...
 
}catch(Exception ex)
 {
  //...code here
 }
finally {
 //best close
 if (conAdodb != null && conAdodb.State != 0)
  conAdodb.Close();
  
 System.Runtime.InteropServices.Marshal.ReleaseComObject(tCat);
 GC.Collect();
 GC.WaitForPendingFinalizers();
}