# [solved] Mit Mono und C# auf mdb-Dateien zugreifen?

## Battlestar Gentoo

Hallo,

ich weiß gar nicht wo ich anfangen soll, bei all Herumfummeln und Herumfrickeln, das ich heute schon hinter mir habe. 

Jedenfalls muss ich unbedingt die Daten aus einem Microsoft-mdb-File auslesen können, und zwar mit C#.

Es fängt schon mal damit an, dass C# in Mono offensichtich nur unzureichend implementiert wurde, da ein using System.Data.OleDb nicht gekannt wird.

Offensichtlich ist die Lösung, dass man es mit 

```
mcs -r:System.Data.dll *.cs -out:Main.exe

```

kompilieren muss, aus welchem Grund auch immer. 

Wie auch immer, das Ausführen von Main.exe schafft mit folgendem Testprogramm keinen Datenbankzugriff, da nur irgendwelche Fehlermeldungen kamen:

```
using System;

using System.Data;

using System.Data.OleDb;

namespace Datenbankprogramm  {

      public class DataReader   {

         

         private OleDbConnection connection;

         private String connectionString = "provider = Microsoft.JET.OLEDB.4.0;"

                                        + @"data source = \home\markus\Csharp\schule2000.mdb";

      

      private void OpenConnection()   {

          try  {

             connection = new OleDbConnection();

             connection.ConnectionString = connectionString;

             connection.Open();

             Console.WriteLine("Verbindung wurde erfolgreich aufgebaut");

          }

          catch (OleDbException exc)   {

                Console.WriteLine("Fehler1-2: " + exc.Message);

            }       

      }

      

      private void CloseConnection()   {

          connection.Close();

          Console.WriteLine("Verbindung wurde erfolgreich geschlossen");

      }

   }

}
```

Daraufhin fand ich die gdalib. Ich installierte sie, sie scheint auch mehrere Datenbanktypen zu unterstützen, aber, wie könnte es anders sein, kein ODBC. Auf meinen Main.exe-Ausgabefehler hin fand ich eine schlaue Meldung in einer Newsgroup, wo es hieß, man solle ....

this means the config file is empty. You need to create some datasource,

either using the gda-config-tool or, if you've got libgnomedb installed,

by using gnome-database-properties.

Jetzt bin ich leider genauso schlau wie vorher, wobei libgnomedb offensichtlich gar nichts damit zu tun hat.

Das gda-config-tool hilft auch nicht viel weiter. Es liest nur das Konfigurationsfile von ~/.libgda/config ein, und zeigt eine Prompt, mit der man aber nicht besonders viel machen kann:

```
markus@gentoo ~ $ gda-config-tool 

Using configuration file from /home/markus/.libgda/config

gda> help

          help  Display this help.

        config  Enters libgda configuration management mode.

         query  Enters query mode.

          quit  Finish the program.

gda> config

//Das hier wird auch nur deswegen gezeigt, weil ich das File schon händisch bearbeitet habe. Davor zeige es gar nichts an. 

Entity: line 6: parser error : attributes construct error

    <entry name="DSN" type="string" value="URI="/home/markus/Csharp/schule2000.m

                                                ^

Entity: line 6: parser error : Couldn't find end of Start Tag entry line 6

    <entry name="DSN" type="string" value="URI="/home/markus/Csharp/schule2000.m

                                                ^

** (process:25070): WARNING **: File empty or not well-formed.

config> query

Error: Unknown command

config> query test

Error: Unknown command

config> 

```

Daten kann man damit zwar ins Konfigurationsfile schreiben, aber was nutzt es, wenn man nicht weiß, was man eintragen muss:

```
markus@gentoo ~ $ gda-config-tool --help

Usage: gda-config-tool [OPTION...]

  -c, --config-file=filename     File to load the configuration from.

  -l, --list-providers           Lists installed providers

  -L, --list-datasources         Lists configured datasources

  -n, --name=STRING              User-assigned name for this connection.

  -u, --user=STRING              User name to pass to the provider.

  -p, --password=STRING          Password for the given user to connect to the

                                 DB backend.

  -P, --provider=STRING          Provider name.

  -d, --DSN=STRING               Semi-colon separated string with name=value

                                 options to pass to the GDA provider.

Help options:

  -?, --help                     Show this help message

  --usage                        Display brief usage message

```

Danach dachte ich daran, die unixODBC-Treiber zu installieren, und als ich versuchte sie irgendwie zu benutzen, kamen nur Fehlermeldungen, die wohl den Anschein erwecken, dass dieser Treiber nicht funktionstüchtig ist:

```
markus@gentoo ~ $ ODBCConfig  

ODBCConfig: symbol lookup error: /usr/lib/libodbcinstQ.so.1: undefined symbol: iniElement

```

dann lies ich das mal mit diesem Treiber, und versucht mit gdalib wieder mein Glück. 

Dabei kann man neue Datenbanktypen hinzufügen, aber blöde Sache, wenn man nicht weiß, welche Parameter man wie setzen muss.

Beispielsweise sieht die Ausgabe für mySQL so aus:

```
Provider name: MySQL

Description: Provider for MySQL databases

DSN parameters: DATABASE HOST PORT UNIX_SOCKET USE_SSL

Location: /usr/lib/libgda/providers/libgda-mysql.so

```

Und wie sähe die Ausgabe für mdb-Dateien aus? Welcher Datenbanktyp ist das eigentlich?

Dann fing ich eben mal an etwas herumzuprobieren, und werkte an dem User-Config-File herum:

```
markus@gentoo ~ $ cat .libgda/config  

<?xml version="1.0"?>

<libgda-config>

  <section path="/apps/libgda/Datasources/OLEDB">

    <entry name="Provider" type="string" value="Microsoft.JET.OLEDB.4.0" />

    <entry name="Description" type="string" value="OLEDB 4.0 DB" />

    <entry name="DSN" type="string" value="URI="/home/markus/Csharp/schule2000.mdb" />

  </section>

</libgda-config>

```

Dass der DSN-Eintrag wahrscheinlich falsch ist, ist mir schon klar. Wie kommt man aber dazu? Zu DSN fand ich folgendes: http://www.kamath.com/tutorials/tut005_filedsn.asp . Ich weiß aber nicht, wie mir das weiterhelfen könnte. Zumindest reagiert das C#-Programm auf den Eintrag in libgda/config:

```
markus@gentoo ~/Csharp/Uebungsprogramme/Datenbankprogramm $ mono Main.exe          Entity: line 6: parser error : attributes construct error

    <entry name="DSN" type="string" value="URI="/home/markus/Csharp/schule2000.m

                                                ^

Entity: line 6: parser error : Couldn't find end of Start Tag entry line 6

    <entry name="DSN" type="string" value="URI="/home/markus/Csharp/schule2000.m

                                                ^

** (System.Data.OleDb:21489): WARNING **: File empty or not well-formed.

** (System.Data.OleDb:21489): CRITICAL **: gda_connection_get_errors: assertion `GDA_IS_CONNECTION (cnc)' failed

```

Hat irgendjemand irgend eine Ahnung davon, was man hier machen muss, und dieses Microsoft-Ding zum laufen zu bekommen?

----------

## TheCurse

Muss es denn unbedingt Mono/Linux sein? Unter Windows ist das ganze viel einfacher zu implementieren! Sagen wir mal so: Die mdb wurde auch sicherlich unter Windows erstellt. Also liegt es doch auch irgendwie nahe, die dort zum Beispiel in eine CSV Datei zu exportieren oder so... Dafür bräuchte man nur kurz nach mdb2csv bei google suchen und findet etwas passendes. 

Prinzipiell sollte der Datenbankzugriff auch wie in deinem Beispiel funktionieren, allerdings sind "irgendwelche Fehlermeldungen" nicht gerade aufschlußreich, was du wohl falsch gemacht hast. Ist die data source so korrekt? Sieht mir irgendwie komisch aus mit den \s, insbesondere, weil ein \ in C# strings eine escape sequenz einleiten... Wenn du ein \ willst musst du \\ schreiben! War das vielleicht der Fehler? Probier es doch erstmal unter Windows/.NET zum laufen zu bekommen. Außerdem kann dein Testprogramm auch noch nicht komplett sein, oder doch? Es gibt ja gar keinen Einstiegspunkt...

Oha, da hab ich nochwas gefunden: 

```
    <entry name="DSN" type="string" value="URI="/home/markus/Csharp/schule2000.mdb" /> 
```

Mach da mal ein 

```
    <entry name="DSN" type="string" value="URI='/home/markus/Csharp/schule2000.mdb'" /> 
```

 raus, vielleicht behebt das schon deine Probleme.

Gruß,

Tim

----------

## Battlestar Gentoo

Hallo,

also vorerst Windows ist kein Thema. Ich habe zwar auf einer anderen Platte noch eine alte XP-Installation, aber die ist 4 Jahre alt, d.H. jeglicher Virenschutz o.ä. quasi nicht vorhanden. Darüberhinaus habe ich schon gar kein .NET-Framework. 

Prinzipiell sollte der Datenbankzugriff auch wie in deinem Beispiel funktionieren, allerdings sind "irgendwelche Fehlermeldungen" nicht gerade aufschlußreich,

Die Fehlermeldungen waren ungefähr diese, die ich bereits beschrieb. 

Ist die data source so korrekt? Sieht mir irgendwie komisch aus mit den \s, insbesondere, weil ein \ in C# strings eine escape sequenz einleiten... Wenn du ein \ willst musst du \\ schreiben! War das vielleicht der Fehler? 

Ja, sie ist korrekt. In C# kann ein Klammeraffe vor dem String geschrieben werden, wodurch du diesen nicht mehr mit Escape-Zeichen versehen musst.

Ich versuchte natürlich auch schon Backslashes statt Slashes zu schreiben. Allerdings stimmen wohl die Slashes, da ich mich ja auf keinem Windowssystem befinde. 

Außerdem kann dein Testprogramm auch noch nicht komplett sein, oder doch? Es gibt ja gar keinen Einstiegspunkt... 

Die Main-Methode habe ich natürlich in diesem Posting weggelassen, da diese ohnehin selbstverständlich ist. 

Oha, da hab ich nochwas gefunden:

Code:

    <entry name="DSN" type="string" value="URI="/home/markus/Csharp/schule2000.mdb" />

Da hast du recht. Jetzt erscheint nur mehr eine Fehlermeldung.

Ich glaube aber trotzdem nicht, dass diese Angabe im Config-File überhaupt stimmt. Die anderen Datenbanksysteme habe hier ganz andere gesetzt Werte, wie ich bereits in meinem Orginalposting beschrieb, z.B:

```

DSN parameters: DATABASE HOST PORT UNIX_SOCKET USE_SSL 

```

Dies ist die Fehlermeldung, die jetzt noch auftritt.

```
markus@gentoo ~/Csharp/Uebungsprogramme/Datenbankprogramm $ mono Main.exe 

** (System.Data.OleDb:19344): CRITICAL **: gda_connection_get_errors: assertion `GDA_IS_CONNECTION (cnc)' failed

```

Ich bin gerade dabei, den neuesten unixODBC-Treiber zu installieren. Ich hoffe nur, dass dieser funktionstüchtig ist, und mal sehen, ob der vielleicht irgendwas bewirkt. Ich weiß eigentlich noch immer nicht genau, was ich denn eigentlich nun benötige.

----------

## achimh

Alternativ gibt es noch die mdbtools, die auch in Portage sind. Damit kannst du auf die Access Datenbank zugreifen, rudimentäre SQL statements übers sqlite absetzen und Daten exportieren (falls es nur mal wichtig ist an die bestehenden Daten zu kommen).

Bei Mono kenne ich mich leider nicht aus.

----------

## Battlestar Gentoo

Hi,

die mdbtools sind zwar installiert. Jetzt habe ich aber gerade bemerkt, dass sie mit "-odbc" installiert sind. Ich lasse es gerade nochmals durchlaufen, mal sehen, was es bringt. Dabei kam ich drauf, dass libdga ebenfalls nicht mit odbc und mdb kompiliert wurde. Vielleicht bringt mich das gleich mal einen entscheidenen Schritt weiter.

----------

## Battlestar Gentoo

Jetzt ist in gda zwar OBDC und MS Access vorhanden....

```
markus@gentoo ~ $ gda-config-tool -l

---Providers list---

Provider name: Berkeley-DB

Description: Provider for Berkeley databases

DSN parameters: FILE DATABASE

Location: /usr/lib/libgda/providers/libgda-bdb.so

---

Provider name: MySQL

Description: Provider for MySQL databases

DSN parameters: DATABASE HOST PORT UNIX_SOCKET USE_SSL

Location: /usr/lib/libgda/providers/libgda-mysql.so

---

Provider name: PostgreSQL

Description: Provider for PostgreSQL databases

DSN parameters: DATABASE SEARCHPATH HOST HOSTADDR OPTIONS PORT REQUIRESSL

                TTY

Location: /usr/lib/libgda/providers/libgda-postgres.so

---

Provider name: LDAP

Description: Provider for LDAP directory

DSN parameters: FLAGS HOST PORT BINDDN AUTHMETHOD

Location: /usr/lib/libgda/providers/libgda-ldap.so

---

Provider name: XML

Description: XML provider, based on the libgda XML database format

DSN parameters: URI

Location: /usr/lib/libgda/providers/libgda-xml.so

---

Provider name: MS Access

Description: Provider for Microsoft Access files

DSN parameters: FILENAME

Location: /usr/lib/libgda/providers/libgda-mdb.so

---

Provider name: ODBC

Description: Provider for ODBC data sources

DSN parameters: STRING

Location: /usr/lib/libgda/providers/libgda-odbc.so

```

...aber das Programm funktioniert immer noch nicht:

```

markus@gentoo ~/Csharp/Uebungsprogramme/Datenbankprogramm $ mono Main.exe       Entity: line 2: parser error : Start tag expected, '<' not found

^

** (System.Data.OleDb:20356): WARNING **: File empty or not well-formed.

** (System.Data.OleDb:20356): CRITICAL **: gda_connection_get_errors: assertion `GDA_IS_CONNECTION (cnc)' failed

```

Es funktioniert übrigens mit zwei verschiedenen Access-Files nicht, da genau die gleiche Fehlermeldung kommt, also muss der Fehler nun wieder irgendwo anders liegen. 

Desweiteren versuchte ich auch im C#-File den Providernamen zu einem der jetzt in der dga-Datei angezeigten Provider zu ändern, aber an den Fehlermeldungen ändert sich weder etwas, noch funktioniert es überhaupt endlich mal.

----------

## TheCurse

Schau nochmal über die XML Datei rüber. Da scheint irgendwas nicht in Ordnung zu sein (lies die Fehlermeldung). Er findet kein start tag, poste vielleicht nochmal die komplette Datei, dann finden wir es vielleicht

----------

## Battlestar Gentoo

Nun kam ich schließlich zu der Annahme, es könne an "Entity" liegen, da diese Ausgabe in der Konsole erscheint. Daraufhin wollte ich entity, einen XML-Parser installieren, aber wie könnte es denn anders sein, die Installation bricht natürlich ab:

```
gcc -DHAVE_CONFIG_H -I. -I. -I.. -DJS_EXT_DIR=\"/usr/lib/entity\" -DJS_SYSBOOT_D       IR=\"/usr/lib/entity\" -O2 -march=pentium4 -O2 -pipe -I/usr/X11R6/include -I/usr       /include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -Wall -I/usr/lo       cal/ssl/include/ -L/usr/local/ssl/lib/ -c iostream.c  -fPIC -DPIC -o iostream.lo

In file included from njs/internal.h:96,

                 from iostream.c:30:

./njs/njs.h:275: warning: type qualifiers ignored on function return type

./njs/njs.h:287: warning: type qualifiers ignored on function return type

./njs/njs.h:469: warning: type qualifiers ignored on function return type

iostream.c: In function 'js_iostream_read':

iostream.c:236: error: invalid lvalue in assignment

iostream.c: In function 'js_iostream_write':

iostream.c:293: error: invalid lvalue in assignment

make[3]: *** [iostream.lo] Fehler 1

make[3]: Leaving directory `/var/tmp/portage/dev-lang/entity-0.7.2-r1/work/entit       y-0.7.2/libentitynjs'

make[2]: *** [all-recursive] Fehler 1

make[2]: Leaving directory `/var/tmp/portage/dev-lang/entity-0.7.2-r1/work/entit       y-0.7.2/libentitynjs'

make[1]: *** [all-recursive] Fehler 1

make[1]: Leaving directory `/var/tmp/portage/dev-lang/entity-0.7.2-r1/work/entit       y-0.7.2'

make: *** [all-recursive-am] Fehler 2

!!! ERROR: dev-lang/entity-0.7.2-r1 failed.

Call stack:

  ebuild.sh, line 1614:   Called dyn_compile

  ebuild.sh, line 971:   Called qa_call 'src_compile'

  environment, line 1216:   Called src_compile

  entity-0.7.2-r1.ebuild, line 61:   Called die

!!! (no error message)

!!! If you need support, post the topmost build error, and the call stack if rel       evant.

!!! A complete build log is located at '/var/tmp/portage/dev-lang/entity-0.7.2-r       1/temp/build.log'.

```

----------

## Battlestar Gentoo

 *TheCurse wrote:*   

> Schau nochmal über die XML Datei rüber. Da scheint irgendwas nicht in Ordnung zu sein (lies die Fehlermeldung). Er findet kein start tag, poste vielleicht nochmal die komplette Datei, dann finden wir es vielleicht

 

Welche XML-Datei ist damit überhaupt gemeint? Ich habe hier keine XML-Dateien?

----------

## TheCurse

Sorry, ich meinte die .libgda/config. Ist im XML Format.

----------

## Battlestar Gentoo

In dieser Datei steht seit der Aufnahme von ODBC und MS Access in die Konfiguration gar nichts mehr drin.

ich frage mich allerdings, wo diese Daten gespeichert werden, da in /etc nur folgendes zu finden ist:

```
markus@gentoo ~/Csharp/Uebungsprogramme/Datenbankprogramm $ cat /etc/libgda/config 

<?xml version="1.0"?>

<libgda-config>

        <section path="/apps/libgda/Datasources/Default">

                <entry name="Provider" type="string" value="XML"/>

                <entry name="Username" type="string" value="nouser"/>

                <entry name="DSN" type="string" value="URI=/tmp/gnome-db-test.db"/>

                <entry name="Description" type="string" value="Default data source"/>

        </section>

</libgda-config>

```

----------

## TheCurse

Hmm, ich seh den Fehler nicht... 

Interessant könnte für dich auch gda-sharp sein, ich schau mir das gerade an und teste mal ein bisschen. Wenn ich zugriff auf ne Access Datenbank habe poste ich dir mal die Lösung sozusagen.

----------

## TheCurse

Ich hab mal ein bisschen rumgespielt, aber so ganz komm ich damit nicht zurecht, weil ich ein SIGSEGV bekomme... Liegt wahrscheinlich an meiner Version... Kannst dir ja mal den Codeschnipsel hier anschauen, ob dir das weiterhilft: 

```
         Gda.Application.Init("mdbtest", "0.1");

         Gda.Client client = new Gda.Client();

         Gda.Connection conn = client.OpenConnection("test", "nouser", "", Gda.ConnectionOptions.ReadOnly);

         

         if (conn != null)

         {

            if (conn.IsOpen)

            {

               Gda.DataModel model = conn.GetSchema(Gda.ConnectionSchema.Databases, new Gda.ParameterList());

               for (int colid = 0; colid < model.NColumns; colid++)

               {

                  Console.WriteLine(model.GetColumnTitle(colid));

                  for (int rowid = 0; rowid < model.NRows; rowid++)

                  {

                     Gda.Value v = model.GetValueAt(colid, rowid);

                     Console.WriteLine(v.String);

                  }   

               }         

            }

         }
```

 Der SIGSEGV kommt in der Zeile 

```
Gda.Value v = model.GetValueAt(colid, rowid);
```

Also wenn du die methode nicht brauchst, der Rest scheint zu funktionieren.

Dazu die ~/.libgda/config:

```
<?xml version="1.0"?>

<libgda-config>

  <section path="/apps/libgda/Datasources/test">

    <entry name="DSN" type="string" value="FILENAME=/home/xxx/test.mdb"/>

    <entry name="Description" type="string" value="Testmdb"/>

    <entry name="Password" type="string" value=""/>

    <entry name="Provider" type="string" value="MS Access"/>

    <entry name="Username" type="string" value="nouser"/>

  </section>

</libgda-config>
```

----------

## Battlestar Gentoo

Hallo,

ehrlich gesagt kenne ich mich schon überhaupt nicht mehr aus. 

Muss ich gda nun speziell im Code irgendwie ansprechen, oder wie funktioniert das Zugreifen jetzt eigentlich? In Mono selbst scheint ja sowieso alles irgendwie abzulaufen, da die "using"-Anweisungen bei System.Data.... nur Fehlermeldungen hervorbringen (blabla missing Assembly reference...), aber das Kompilieren mit 

```
$ mcs -r:System.Data.dll *.cs -out:Main.exe
```

funktioniert.

Du hast mich allerdings auf eine Idee gebracht. Sind die Ausgaben von gda-config-tool vielleicht nur die Vorlage, um das Config-File zu erstellen? 

Ich schrieb mal einige Angaben in das Config-File und bekomme beim Ausführen der Main.exe nur mehr folgende Meldung:

```
$ mono Main.exe 

** (System.Data.OleDb:32309): CRITICAL **: gda_connection_get_errors: assertion `GDA_IS_CONNECTION (cnc)' failed

```

Was soll das bedeuten? Bei Google findet man auch nicht wirklich sinnvolels dazu. 

Meine Config-Datei sieht nun so aus:

```
<?xml version="1.0"?>

<libgda-config>

  <section path="/apps/libgda/Datasources/MS Access">

    <entry name="Provider" type="string" value="MS Access"/>

    <entry name="DSN" type="string" value="FILENAME=/home/markus/Csharp/schule2000.mdb"/>

    <entry name="Description" type="string" value="Test mdb"/>

    <entry name="Password" type="string" value=""/>

    <entry name="Username" type="string" value="nouser"/> 

  </section>

</libgda-config>
```

Was ist eigentlich dieser section-path. Physisch kann er nicht sein, da ich diesen Pfad mit "find" nicht finde.

----------

## Battlestar Gentoo

```
         

private OleDbConnection connection = new OleDbConnection("MS Access");

```

Das war anscheinend die ganze Hexerei, da ich nun bei Open()-Anweisungen keine Fehlermeldungen mehr bekomme. Offensichtlich holt er sich die Daten aus dem Config-File. Ich habe jetzt zwar keine Zeit mehr Abfragen zu testen, aber es sieht so aus, als würde es funktionieren. 

Nachtrag:

In Mono in der "Solution"->References->rechte Maustaste->Edit references kann man die nicht gefundenen Referenzen hinzufügen. Somit muss man es auch nicht mehr aus der Konsole starten, was ohnehin komischerweise nicht richtig funktoniert hat wie man beim funktionierenden Programm nun erkennen konnte, da das Programm irgendwie manche Console.WriteLine-Anweisungen ignorierte.

----------

## firefly

 *Battlestar Gentoo wrote:*   

> Hallo,
> 
> ehrlich gesagt kenne ich mich schon überhaupt nicht mehr aus. 
> 
> Muss ich gda nun speziell im Code irgendwie ansprechen, oder wie funktioniert das Zugreifen jetzt eigentlich? In Mono selbst scheint ja sowieso alles irgendwie abzulaufen, da die "using"-Anweisungen bei System.Data.... nur Fehlermeldungen hervorbringen (blabla missing Assembly reference...), aber das Kompilieren mit 
> ...

 

Das sehe ich nicht als problem an, wenn du die Dlls angeben musst. Unter Windows mit dem Visual Studio fügt die IDE die passenden angaben über die benötigten DLL referencen hinzu, wenn das Projekt übersetzt wird.

----------

