Come sicuramente molti di voi sapranno, il
Business Data Catalog costituisce una delle novità più interessanti di MOSS 2007. Questo componente permette infatti di risolvere in maniera abbastanza elegante l'accesso a sorgenti dati esterne (di tipo Database o Web Service) tramite la definizione di un
Application Metadata Model, un documento XML che funge da wrapper. Al suo interno, infatti, vengono definiti oltre al meccanismo di autenticazione verso la sorgenti dati stessa, anche gli oggetti di business (definibili come Entità) con i relativi metodi, azioni ed associazioni che MOSS 2007 può utilizzare per l'interazione con la sorgente dati. Molti sono gli scenari applicativi ottenibili tramite questo strumento: si va dall' uso delle Web Part bult-in della famiglia Business Data fino all'integrazione con il servizio Enterprise Search che permette di sfruttare il Metadata Application Model registrato nel BDC per indicizzare i contenuti della sorgente dati esterna... sicuramente potente come feature!!!
Sfiga ha voluto che il mio primo lavoro che coinvolgesse il BDC, prevedesse l'integrazione di una sorgente dati Microsoft Access 97 (!!!!). Bene, considerando che Microsoft fornisce ufficialmente
due esempi e mezzo per la creazione di un Application Metadata Model (Sql Server 2005, Web Service...e Oracle) e che in rete non sembri un argomento molto gettonato (e quando trovi qualcuno che ne parla grazie alla legge di Murphy non fa al caso tuo), la prima cosa ho provato a fare preliminarmente è stata ricercare un tool in grado di automatizzare il più possibile il processo di creazione dell' Application Metadata Model... OK ... search search search... trovato!
BDC Metaman! Vediamo: ... bla bla bla bla .... sorgenti dati supportate per ora:
Sql Server 2000/2005. Sigh! Bene, rimbocchiamoci le maniche e creiamoci a manina l'Application Metadata Model!!!
Le cose sono andate liscie, anche perché l' Administration Object Model di MOSS 2007 permette di testare la connessione alla sorgente dati e l'effettivo funzionamento dei metodi definiti per l'accesso in lettura (
maggiori info). Tuttavia, due sono gli ostacoli che ho incontrato (in realtà uno conseguenza dell'altro):
1) Non sono riuscito a far funzionare la connessione al DB Access utilizzando 'Oledb' come DatabaseAccessProvider (frustrante questa cosa... se qualcuno di voi ci riesce NON lo voglio sapere.. ;)). Quindi, mi sono dovuto creare un DSN di sistema ed utilizzare Odbc.
...
<LobSystemInstance Name="xxxInstance">
<Properties>
<Property Name="AuthenticationMode"
Type="Microsoft.Office.Server.ApplicationRegistry.SystemSpecific.Db.DbAuthenticationMode">PassThrough
</Property>
<Property Name="DatabaseAccessProvider"
Type="Microsoft.Office.Server.ApplicationRegistry.SystemSpecific.Db.DbAccessProvider">Odbc
</Property>
<Property Name="RdbConnection Data Source" Type="System.String">'Driver={Microsoft Access Driver
(*.mdb)};DSN=xxxDB;Trusted_Connection=True;'
</Property>
<Property Name="RdbConnection Integrated Security" Type="System.String">SSPI</Property>
<Property Name="RdbConnection Pooling" Type="System.String">false</Property>
</Properties>
</LobSystemInstance>
...
2) Adesso arriva il bello!!! In uno sharepointblog leggo: "When the BDC connects to the ODBC driver, ... very strange thing: It is not possible to use more than one parameter in the SQL query! ... " Ovvero, se utilizziamo ODBC come provider per l'accesso ai dati, possiamo specificare al massimo UN SOLO PARAMETRO di input alla nostra query SQL. Quindi, come mostrato nel seguente listato, la clausola WHERE dello statement SQL per selezionare i dati dal mio DB Access può prevedere al più un solo valore di input per filtrare i dati.... SONO SVENUTO!!!!
Fortunatamente mi è andata bene: avevo a disposizione un unico campo chiave primaria per le tabelle che mi interessavano e quindi non ho avuto problemi.
Ad ogni modo, non voglio immaginare il caso in cui si necessiti di due paramteri per identificare univocamente un record!!!
...
<
Method Name="GetSchedaxxx">
<Properties>
<Property Name="RdbCommandText" Type="System.String">
SELECT ... FROM ... WHERE Schede.ID_Scheda = ?
</Property>
<Property Name="RdbCommandType" Type="System.Data.CommandType">Text</Property>
</Properties>
<Parameters>
<Parameter Direction="In" Name="@Scheda_ID">
<TypeDescriptor TypeName="System.Int32" IdentifierName="ID_Scheda" Name="SchedaID" />
</Parameter>
<Parameter Direction="Return" Name="Schedexxx">
...
</Parameter>
</Parameters>
<MethodInstances>
<MethodInstance Name="SchedaxxxSpecificFinderInstance"
Type="SpecificFinder" ReturnParameterName="Schedexxx" />
</MethodInstances>
</Method>
...