Verwenden von SQLite.NET mit Xamarin.iOS

Die SQLite.NET Bibliothek, die Xamarin empfiehlt, ist ein einfacher ORM, mit dem Sie Objekte in der lokalen SQLite-Datenbank auf einem iOS-Gerät speichern und abrufen können. ORM steht für Object Relational Mapping – eine API, mit der Sie "Objekte" aus einer Datenbank speichern und abrufen können, ohne SQL-Anweisungen zu schreiben.

Verwendung

Um die SQLite.NET-Bibliothek in eine Xamarin-App einzuschließen, fügen Sie dem Projekt das folgende NuGet-Paket hinzu:

SQLite.NET NuGet-Paket

Es sind eine Reihe verschiedener SQLite-Pakete verfügbar. Achten Sie darauf, das richtige Paket auszuwählen (dies ist möglicherweise nicht das beste Ergebnis in der Suche).

Wichtig

SQLite.NET ist eine Drittanbieterbibliothek, die vom praeclarum/sqlite-net-Repository unterstützt wird.

Sobald Sie die SQLite.NET-Bibliothek verfügbar haben, führen Sie die folgenden drei Schritte aus, um sie für den Zugriff auf eine Datenbank zu verwenden:

  1. Hinzufügen einer using-Anweisung : Fügen Sie die folgende Anweisung zu den C#-Dateien hinzu, in denen Datenzugriff erforderlich ist:

    using SQLite;
    
  2. Erstellen einer leeren Datenbank : Ein Datenbankverweis kann erstellt werden, indem der Dateipfad an den SQLiteConnection-Klassenkonstruktor übergeben wird. Sie müssen nicht überprüfen, ob die Datei bereits vorhanden ist. Sie wird bei Bedarf automatisch erstellt, andernfalls wird die vorhandene Datenbankdatei geöffnet.

    var db = new SQLiteConnection (dbPath);
    

    Die dbPath-Variable sollte gemäß den regeln bestimmt werden, die weiter oben in diesem Dokument erläutert wurden.

  3. Daten speichern : Nachdem Sie ein SQLiteConnection-Objekt erstellt haben, werden Datenbankbefehle ausgeführt, indem die zugehörigen Methoden wie CreateTable und Insert wie folgt aufgerufen werden:

    db.CreateTable<Stock> ();
    db.Insert (newStock); // after creating the newStock object
    
  4. Daten abrufen : Verwenden Sie die folgende Syntax, um ein Objekt (oder eine Liste von Objekten) abzurufen:

    var stock = db.Get<Stock>(5); // primary key id of 5
    var stockList = db.Table<Stock>();
    

Beispiel für den einfachen Datenzugriff

Der DataAccess_Basic Beispielcode für dieses Dokument sieht bei der Ausführung unter iOS wie folgt aus. Der Code veranschaulicht, wie einfache SQLite.NET-Vorgänge ausgeführt werden, und zeigt die Ergebnisse als Text im Standard Fenster der Anwendung an.

iOS

Beispiel für iOS-SQLite.NET

Das folgende Codebeispiel zeigt eine gesamte Datenbankinteraktion mithilfe der SQLite.NET-Bibliothek, um den zugrunde liegenden Datenbankzugriff zu kapseln. Es zeigt Folgendes an:

  1. Erstellen der Datenbankdatei
  2. Einfügen einiger Daten durch Erstellen von Objekten und anschließendes Speichern
  3. Abfragen der Daten

Sie müssen die folgenden Namespaces einschließen:

using SQLite; // from the github SQLite.cs class

Dies erfordert, dass Sie IHREM Projekt SQLite hinzugefügt haben, wie hier hervorgehoben. Beachten Sie, dass die SQLite-Datenbanktabelle durch Hinzufügen von Attributen zu einer Klasse (der Stock -Klasse) anstelle eines CREATE TABLE-Befehls definiert wird.

[Table("Items")]
public class Stock {
    [PrimaryKey, AutoIncrement, Column("_id")]
    public int Id { get; set; }
    [MaxLength(8)]
    public string Symbol { get; set; }
}
public static void DoSomeDataAccess () {
       Console.WriteLine ("Creating database, if it doesn't already exist");
   string dbPath = Path.Combine (
        Environment.GetFolderPath (Environment.SpecialFolder.Personal),
        "ormdemo.db3");
   var db = new SQLiteConnection (dbPath);
   db.CreateTable<Stock> ();
   if (db.Table<Stock> ().Count() == 0) {
        // only insert the data if it doesn't already exist
        var newStock = new Stock ();
        newStock.Symbol = "AAPL";
        db.Insert (newStock);
        newStock = new Stock ();
        newStock.Symbol = "GOOG";
        db.Insert (newStock);
        newStock = new Stock ();
        newStock.Symbol = "MSFT";
        db.Insert (newStock);
    }
    Console.WriteLine("Reading data");
    var table = db.Table<Stock> ();
    foreach (var s in table) {
        Console.WriteLine (s.Id + " " + s.Symbol);
    }
}

Die Verwendung des [Table] Attributs ohne Angabe eines Tabellennamenparameters führt dazu, dass die zugrunde liegende Datenbanktabelle denselben Namen wie die Klasse hat (in diesem Fall "Stock"). Der tatsächliche Tabellenname ist wichtig, wenn Sie SQL-Abfragen direkt für die Datenbank schreiben, anstatt die ORM-Datenzugriffsmethoden zu verwenden. Auf ähnliche Weise ist das [Column("_id")] Attribut optional, und wenn keine Spalte vorhanden ist, wird der Tabelle eine Spalte mit demselben Namen wie die Eigenschaft in der Klasse hinzugefügt.

SQLite-Attribute

Zu den allgemeinen Attributen, die Sie auf Ihre Klassen anwenden können, um zu steuern, wie sie in der zugrunde liegenden Datenbank gespeichert werden, gehören:

  • [PrimaryKey] – Dieses Attribut kann auf eine ganzzahlige Eigenschaft angewendet werden, um zu erzwingen, dass es sich um den Primärschlüssel der zugrunde liegenden Tabelle handelt. Zusammengesetzte Primärschlüssel werden nicht unterstützt.
  • [AutoIncrement] – Dieses Attribut bewirkt, dass der Wert einer ganzzahligen Eigenschaft für jedes neue Objekt, das in die Datenbank eingefügt wird, automatisch erhöht wird.
  • [Column(name)] – Der name Parameter legt den Namen der zugrunde liegenden Datenbankspalte fest.
  • [Table(name)] – Markiert die Klasse als in einer zugrunde liegenden SQLite-Tabelle mit dem angegebenen Namen gespeichert werden kann.
  • [MaxLength(value)] – Schränken Sie die Länge einer Texteigenschaft ein, wenn versucht wird, eine Datenbankeinfügung durchzuführen. Die Verwendung von Code sollte dies vor dem Einfügen des -Objekts überprüfen, da dieses Attribut nur "aktiviert" wird, wenn ein Datenbankeinfüge- oder -aktualisierungsvorgang versucht wird.
  • [Ignore] – Bewirkt, dass SQLite.NET diese Eigenschaft ignoriert. Dies ist besonders nützlich für Eigenschaften mit einem Typ, der nicht in der Datenbank gespeichert werden kann, oder für Eigenschaften, bei denen Modellsammlungen, die nicht automatisch aufgelöst werden können, SQLite sein können.
  • [Eindeutig] – Stellt sicher, dass die Werte in der zugrunde liegenden Datenbankspalte eindeutig sind.

Die meisten dieser Attribute sind optional. Sie sollten immer einen ganzzahligen Primärschlüssel angeben, damit Auswahl- und Löschabfragen effizient für Ihre Daten ausgeführt werden können.

Komplexere Abfragen

Die folgenden Methoden für SQLiteConnection können verwendet werden, um andere Datenvorgänge auszuführen:

  • Einfügen : Fügt der Datenbank ein neues Objekt hinzu.
  • Erhalten<T> : Versucht, ein Objekt mithilfe des Primärschlüssels abzurufen.
  • Tabelle<T> – Gibt alle Objekte in der Tabelle zurück.
  • Löschen : Löscht ein Objekt mit seinem Primärschlüssel.
  • Abfrage<T> : Führen Sie eine SQL-Abfrage aus, die eine Anzahl von Zeilen (als Objekte) zurückgibt.
  • Ausführen : Verwenden Sie diese Methode (und nicht Query ), wenn Sie keine Zeilen zurück aus der SQL-Instanz erwarten (z. B. INSERT-, UPDATE- und DELETE-Anweisungen).

Abrufen eines Objekts anhand des Primärschlüssels

SQLite.Net stellt die Get-Methode bereit, um ein einzelnes Objekt basierend auf seinem Primärschlüssel abzurufen.

var existingItem = db.Get<Stock>(3);

Auswählen eines Objekts mithilfe von Linq

Methoden, die Sammlungen zurückgeben, unterstützen IEnumerable<T> , sodass Sie Linq verwenden können, um den Inhalt einer Tabelle abzufragen oder zu sortieren. Der folgende Code zeigt ein Beispiel, in dem Linq verwendet wird, um alle Einträge herauszufiltern, die mit dem Buchstaben "A" beginnen:

var apple = from s in db.Table<Stock>()
    where s.Symbol.StartsWith ("A")
    select s;
Console.WriteLine ("-> " + apple.FirstOrDefault ().Symbol);

Auswählen eines Objekts mithilfe von SQL

Obwohl SQLite.Net objektbasierten Zugriff auf Ihre Daten ermöglichen können, müssen Sie manchmal eine komplexere Abfrage durchführen, als Linq zulässt (oder Sie benötigen möglicherweise eine höhere Leistung). Sie können SQL-Befehle mit der Query-Methode verwenden, wie hier gezeigt:

var stocksStartingWithA = db.Query<Stock>("SELECT * FROM Items WHERE Symbol = ?", "A");
foreach (var s in stocksStartingWithA) {
    Console.WriteLine ("a " + s.Symbol);
}

Wichtig

Beim direkten Schreiben von SQL-Anweisungen erstellen Sie eine Abhängigkeit von den Namen von Tabellen und Spalten in Ihrer Datenbank, die aus Ihren Klassen und deren Attributen generiert wurden. Wenn Sie diese Namen in Ihrem Code ändern, müssen Sie alle manuell geschriebenen SQL-Anweisungen aktualisieren.

Löschen eines Objekts

Der Primärschlüssel wird verwendet, um die Zeile zu löschen, wie hier gezeigt:

var rowcount = db.Delete<Stock>(someStock.Id); // Id is the primary key

Sie können überprüfen rowcount , wie viele Zeilen betroffen (in diesem Fall gelöscht) waren.

Verwenden von SQLite.NET mit mehreren Threads

SQLite unterstützt drei verschiedene Threadingmodi: Einzelthread, Multithread und Serialisiert. Wenn Sie über mehrere Threads ohne Einschränkungen auf die Datenbank zugreifen möchten, können Sie SQLite für die Verwendung des serialisierten Threadingmodus konfigurieren. Es ist wichtig, diesen Modus frühzeitig in Ihrer Anwendung festzulegen (z. B. am Anfang der OnCreate Methode).

Um den Threadingmodus zu ändern, rufen Sie SqliteConnection.SetConfig im Namespace auf Mono.Data.Sqlite . Mit dieser Codezeile wird beispielsweise SQLite für den serialisierten Modus konfiguriert:

using Mono.Data.Sqlite;
...
SqliteConnection.SetConfig(SQLiteConfig.Serialized);