Uso di SQLite.NET con Xamarin.iOS

La libreria SQLite.NET consigliata da Xamarin è un ORM di base che consente di archiviare e recuperare oggetti nel database SQLite locale in un dispositivo iOS. ORM è l'acronimo di Object Relational Mapping( API che consente di salvare e recuperare "oggetti" da un database senza scrivere istruzioni SQL.

Utilizzo

Per includere la libreria SQLite.NET in un'app Xamarin, aggiungere il pacchetto NuGet seguente al progetto:

SQLite.NET NuGet package

Sono disponibili diversi pacchetti SQLite. Assicurarsi di scegliere quello corretto (potrebbe non essere il risultato principale nella ricerca).

Importante

SQLite.NET è una libreria di terze parti supportata dal repository praeclarum/sqlite-net.

Dopo aver ottenuto la libreria SQLite.NET disponibile, seguire questa procedura per usarla per accedere a un database:

  1. Aggiungere un'istruzione using : aggiungere l'istruzione seguente ai file C# in cui è necessario l'accesso ai dati:

    using SQLite;
    
  2. Creare un database vuoto: è possibile creare un riferimento al database passando il percorso del file al costruttore della classe SQLite Connessione ion. Non è necessario verificare se il file esiste già. Se necessario, verrà creato automaticamente. In caso contrario, verrà aperto il file di database esistente.

    var db = new SQLiteConnection (dbPath);
    

    La variabile dbPath deve essere determinata in base alle regole descritte in precedenza in questo documento.

  3. Salva dati: dopo aver creato un oggetto SQLite Connessione ion, i comandi di database vengono eseguiti chiamando i relativi metodi, ad esempio CreateTable e Insert nel modo seguente:

    db.CreateTable<Stock> ();
    db.Insert (newStock); // after creating the newStock object
    
  4. Recupera dati : per recuperare un oggetto (o un elenco di oggetti) utilizzare la sintassi seguente:

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

Esempio di accesso ai dati di base

Il codice di esempio DataAccess_Basic per questo documento è simile al seguente durante l'esecuzione in iOS. Il codice illustra come eseguire semplici operazioni di SQLite.NET e mostra i risultati come testo nella finestra principale dell'applicazione.

iOS

iOS SQLite.NET sample

L'esempio di codice seguente illustra un'intera interazione del database usando la libreria SQLite.NET per incapsulare l'accesso al database sottostante. Mostra:

  1. Creazione del file di database
  2. Inserimento di alcuni dati creando oggetti e quindi salvandoli
  3. Eseguire query sui dati

È necessario includere questi spazi dei nomi:

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

Ciò richiede l'aggiunta di SQLite al progetto, come evidenziato qui. Si noti che la tabella di database SQLite viene definita aggiungendo attributi a una classe (la Stock classe) anziché a un comando CREATE TABLE.

[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);
    }
}

Se si usa l'attributo [Table] senza specificare un parametro nome tabella, la tabella di database sottostante avrà lo stesso nome della classe (in questo caso "Stock"). Il nome effettivo della tabella è importante se si scrivono query SQL direttamente sul database anziché usare i metodi di accesso ai dati ORM. Analogamente, l'attributo [Column("_id")] è facoltativo e, se assente, verrà aggiunta una colonna alla tabella con lo stesso nome della proprietà nella classe .

Attributi SQLite

Gli attributi comuni che è possibile applicare alle classi per controllare la modalità di archiviazione nel database sottostante includono:

  • [PrimaryKey] : questo attributo può essere applicato a una proprietà integer per forzarlo come chiave primaria della tabella sottostante. Le chiavi primarie composite non sono supportate.
  • [AutoIncrement] : questo attributo causerà l'incremento automatico del valore di una proprietà integer per ogni nuovo oggetto inserito nel database
  • [Column(name)] : il name parametro imposta il nome della colonna di database sottostante.
  • [Table(name)] : contrassegna la classe come in grado di essere archiviata in una tabella SQLite sottostante con il nome specificato.
  • [MaxLength(value)] : limitare la lunghezza di una proprietà di testo quando si tenta di inserire un database. L'utilizzo del codice deve convalidarlo prima di inserire l'oggetto perché questo attributo è "controllato" solo quando viene tentata un'operazione di inserimento o aggiornamento del database.
  • [Ignora] : fa sì che SQLite.NET ignori questa proprietà. Ciò è particolarmente utile per le proprietà che hanno un tipo che non può essere archiviato nel database o proprietà che non possono essere risolte automaticamente come SQLite.
  • [Univoco] : garantisce che i valori nella colonna del database sottostante siano univoci.

La maggior parte di questi attributi è facoltativa. È consigliabile specificare sempre una chiave primaria integer in modo che le query di selezione ed eliminazione possano essere eseguite in modo efficiente sui dati.

Query più complesse

Per eseguire altre operazioni sui dati, è possibile usare i metodi SQLiteConnection seguenti:

  • Insert : aggiunge un nuovo oggetto al database.
  • Get<T> : tenta di recuperare un oggetto usando la chiave primaria.
  • Table<T> : restituisce tutti gli oggetti della tabella.
  • Delete : elimina un oggetto usando la relativa chiave primaria.
  • Query<T> : eseguire una query SQL che restituisce un numero di righe (come oggetti).
  • Execute: usare questo metodo (e non Query ) quando non si prevede che le righe vengano restituite da SQL (ad esempio IN edizione Standard RT, UPDATE e DELETE istruzioni).

Recupero di un oggetto tramite la chiave primaria

SQLite.Net fornisce il metodo Get per recuperare un singolo oggetto in base alla relativa chiave primaria.

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

Selezione di un oggetto tramite Linq

I metodi che restituiscono raccolte supportano IEnumerable<T> in modo da poter usare Linq per eseguire query o ordinare il contenuto di una tabella. Il codice seguente mostra un esempio che usa Linq per filtrare tutte le voci che iniziano con la lettera "A":

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

Selezione di un oggetto tramite SQL

Anche se SQLite.Net può fornire l'accesso basato su oggetti ai dati, a volte potrebbe essere necessario eseguire una query più complessa rispetto a Linq consente (o potrebbe essere necessario ottenere prestazioni più veloci). È possibile usare i comandi SQL con il metodo Query, come illustrato di seguito:

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

Importante

Quando si scrivono istruzioni SQL direttamente, si crea una dipendenza dai nomi di tabelle e colonne nel database, generati dalle classi e dai relativi attributi. Se si modificano tali nomi nel codice, è necessario ricordare di aggiornare eventuali istruzioni SQL scritte manualmente.

Eliminazione di un oggetto

La chiave primaria viene usata per eliminare la riga, come illustrato di seguito:

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

È possibile verificare il rowcount numero di righe interessate (eliminate in questo caso).

Uso di SQLite.NET con più thread

SQLite supporta tre diverse modalità di threading: a thread singolo, multithread e serializzato. Se si vuole accedere al database da più thread senza restrizioni, è possibile configurare SQLite in modo da usare la modalità di threading serializzato . È importante impostare questa modalità all'inizio dell'applicazione, ad esempio all'inizio del OnCreate metodo .

Per modificare la modalità di threading, chiamare SqliteConnection.SetConfig che si trova nello spazio dei Mono.Data.Sqlite nomi . Ad esempio, questa riga di codice configura SQLite per la modalità serializzata :

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