Zum Inhalt springen
  • 0

Komme mal wieder nicht weiter.. (SQLite, C#)


Frage

Geschrieben

Hallo Leute, leider hab ich auch mit Hilfe von Google und Stackoverflow keine Lösung für mein Problem finden können.

Ich möchte eigentlich nur beim Initialisieren der Klasse eine Datenbankdatei anlegen, anschließend die Verbindung öffnen und eine Tabelle hinzufügen.

Hier meine Klasse: 

class AzDBController
    {

        string path;
        SQLiteConnection connection;

        public AzDBController()
        {
            connection = GetConnection();
            CreateTable();
        }

        public SQLiteConnection GetConnection()
        {
            var sqliteFilename = "SQLite.db";
            path = Path.Combine(ApplicationData.Current.LocalFolder.Path, sqliteFilename);
            SQLiteConnection.CreateFile(path);
            connection = new SQLiteConnection(path);
            return connection;
        }

        public void CreateTable() 
        {

            string sSQL = "CREATE TABLE IF NOT EXISTS Kunden" +
                "(IDKunde Integer Primary Key Autoincrement NOT NULL" +
                ", Vorname VARCHAR(200)" +
                ", Nachname VARCHAR(200)";
            connection.ConnectionString = @"Data Source= SQLite.db; Version=3";
            connection.Open();
            SQLiteCommand command = new SQLiteCommand(sSQL, connection);
            command.ExecuteNonQuery();
            connection.Close();

        }

    }

 

Sobald ich die Funktion Open() auf die Connection ausführe bekomme ich folgenden Fehler:

System.Data.SQLite.SQLiteException: "unable to open database file"

Wenn ich den ConnectionString weglasse erhalte ich folgende Exception:

System.ArgumentException: "Invalid ConnectionString format for part "C:\Users\User\AppData\Local\Packages\3aa8bee0-05bb-42cb-9e36-db65cc62d960_5prms3pan9hhr\LocalState\SQLite.db", no equal sign found"

7 Antworten auf diese Frage

Empfohlene Beiträge

  • 1
Geschrieben (bearbeitet)

Noch ein paar Änderungsvorschläge zu @el_pollo_diablos Lösung:

Die Klassenvariable _connection mach keinen Sinn, da sie nur in der Methoe CreateTable() benötigt wird. Das wäre dann eher ein Zeichen dafür, dass diese Methode nicht zur Klasse gehört.

Den Dateinamen zur db-Datei würde ich auch über den Konstruktor reinreichen. Das macht die Klasse flexibler, da man dann unterschiedliche Dateien ansprechen könnte. z.B. eine Produktiv- und eine Test-Datei.

Wenn man mit using arbeitet, dann braucht man auch nicht explizit Close() aufrufen, um die Verbindung zu trennen, da dies schon das Dispose() übernimmt, was aufgerufen wird, wenn man using verwendet.

using System.Data.SQLite;

public class AzDBController
{
    private readonly string dbFileName;
    private readonly string connectionString;

    public AzDBController(string dbFileName)
    {
        this.dbFileName = dbFileName;
        this.connectionString = this.CreateConnectionString();
        this.CreateTable();
    }

    private string CreateConnectionString() => $"Data Source={this.dbFileName}; Version=3";

    public SQLiteConnection GetConnection()
    {
        var connection = new SQLiteConnection(connectionString);
        connection.Open();

        return connection;
    }

    private void CreateTable()
    {
        var sql = @"CREATE TABLE IF NOT EXISTS Kunden (
                        IDKunde INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
                        , Vorname VARCHAR(200)
                        , Nachname VARCHAR(200)
                    )";

        using var connection = this.GetConnection();
        using var command = new SQLiteCommand(sql, connection);
        command.ExecuteNonQuery();
    }
}

Jetzt könnte man sich noch überlegen, ob CreateTable() hier überhaupt sinnvoll ist oder doch nicht lieber in eine separate Klasse auslagert. Wenn man es auslagert, hätte man dann eine Klasse, die die Verbindung zur db-Datei handhabt und eine Klasse, die für die Strukturen der Tabellen zuständig ist.

Bearbeitet von Whiz-zarD
  • 0
Geschrieben (bearbeitet)

Fangen wir mal mit dem offensichtlichsten Problem an:

Das SQL-Statement ist schlicht und ergreifend fehlerhaft... Es fehlt das ");" am Ende. Solche Fehler findest Du am einfachsten, wenn Du das Statement einfach mal über das CLI oder alternativ über irgendeine grafische Oberfläche direkt ausführst.

Danach geht es im C#-Code weiter:

SQLiteConnection.CreateFile(path);

ist ab SQLite-Version 3 wohl nicht mehr erforderlich und die Funktionalität wird von der "Open()"-Methode mit abgedeckt.

Jedoch ist sehr wohl ein gültiger Connection-String notwendig...

In der Methode "GetConnection()" wird zwar der Pfad zusammengebaut, jedoch fehlt mindestens noch "Data Source=" vornweg.

In der Methode "CreateTable()" wird nochmals der Versuch unternommen, einen Connection-String zu bilden, aber leider nur mit dem Dateinamen.

Wenn man alles berücksichtigt und unnötiges entfernt, kann das Resultat dann zum Beispiel so aussehen:

using System.Data.SQLite;
using System.IO;


class AzDBController
{
    SQLiteConnection _connection;

    public AzDBController()
    {
        _connection = GetConnection(@"C:\Projects\sqlitetest\sqlitetest\bin\Debug", "SQLite.db");

        CreateTable();
    }

    public SQLiteConnection GetConnection(string dbDirectory, string dbFileName)
    {
        var dbFullPath = Path.Combine(dbDirectory, dbFileName);

        var connectionString = string.Format(@"Data Source={0}; Version=3", dbFullPath);

        var connection = new SQLiteConnection(connectionString);

        connection.Open();

        return connection;
    }

    public void CreateTable()
    {
        var sSQL =  @"
                    CREATE TABLE IF NOT EXISTS Kunden (
                        IDKunde INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
                        , Vorname VARCHAR(200)
                        , Nachname VARCHAR(200)
                    );
                    ";

        SQLiteCommand command = new SQLiteCommand(sSQL, _connection);

        command.ExecuteNonQuery();

        _connection.Close();
    }
}

Für den stressfreien Anfang würde ich mir angewöhnen, SQL-Statements ähnlich wie das obenstehende zu schreiben, da man sie dann problemlos via Copy&Paste in das CLI oder eine grafische Oberfläche bekommt. Mit mehr Erfahrung wird man das ohnehin schnell ganz anders lösen...

Bearbeitet von el_pollo_diablo
  • 0
Geschrieben
vor 15 Stunden schrieb Whiz-zarD:

Noch ein paar Änderungsvorschläge zu @el_pollo_diablos Lösung:

Die Klassenvariable _connection mach keinen Sinn, da sie nur in der Methoe CreateTable() benötigt wird. Das wäre dann eher ein Zeichen dafür, dass diese Methode nicht zur Klasse gehört.

Den Dateinamen zur db-Datei würde ich auch über den Konstruktor reinreichen. Das macht die Klasse flexibler, da man dann unterschiedliche Dateien ansprechen könnte. z.B. eine Produktiv- und eine Test-Datei.

Wenn man mit using arbeitet, dann braucht man auch nicht explizit Close() aufrufen, um die Verbindung zu trennen, da dies schon das Dispose() übernimmt, was aufgerufen wird, wenn man using verwendet.


using System.Data.SQLite;

public class AzDBController
{
    private readonly string dbFileName;
    private readonly string connectionString;

    public AzDBController(string dbFileName)
    {
        this.dbFileName = dbFileName;
        this.connectionString = this.CreateConnectionString();
        this.CreateTable();
    }

    private string CreateConnectionString() => $"Data Source={this.dbFileName}; Version=3";

    public SQLiteConnection GetConnection()
    {
        var connection = new SQLiteConnection(connectionString);
        connection.Open();

        return connection;
    }

    private void CreateTable()
    {
        var sql = @"CREATE TABLE IF NOT EXISTS Kunden (
                        IDKunde INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
                        , Vorname VARCHAR(200)
                        , Nachname VARCHAR(200)
                    )";

        using var connection = this.GetConnection();
        using var command = new SQLiteCommand(sql, connection);
        command.ExecuteNonQuery();
    }
}

Jetzt könnte man sich noch überlegen, ob CreateTable() hier überhaupt sinnvoll ist oder doch nicht lieber in eine separate Klasse auslagert. Wenn man es auslagert, hätte man dann eine Klasse, die die Verbindung zur db-Datei handhabt und eine Klasse, die für die Strukturen der Tabellen zuständig ist.

Habe deinen Code 1 zu 1 ausprobiert und bekomme immernoch die Exception: System.Data.SQLite.SQLiteException: "unable to open database file" ?

  • 0
Geschrieben
vor 9 Minuten schrieb Whiz-zarD:

Was hast du denn für den Dateinamen angegeben? Ich hab den Code bei mir ausprobiert und es funktioniert.

Hab es mit "myDB" und "myDB.db" versucht. 

ist eine UWP App.

Hab als Verweise: System.Data.SQLite und SQLITE for Universal Windows Platform hinzugefügt.

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Diese Frage beantworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...