Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

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"

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

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

  • Autor
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" ?

  • Autor
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.

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.