Místní databáze .NET MAUI

Browse sample. Procházení ukázky

Databázový stroj SQLite umožňuje aplikacím .NET MAUI (Multi-Platform App UI) .NET načítat a ukládat datové objekty ve sdíleném kódu. Pomocí následujícího postupu můžete integrovat SQLite.NET do aplikací .NET MAUI a ukládat a načítat informace v místní databázi:

  1. Nainstalujte balíček NuGet.
  2. Konfigurujte konstanty.
  3. Vytvořte třídu přístupu k databázi.
  4. Přístup k datům
  5. Pokročilá konfigurace.

Tento článek používá balíček NuGet sqlite-net-pcl k poskytnutí přístupu k databázi SQLite tabulce pro ukládání položek úkolů. Alternativou je použití balíčku NuGet Microsoft.Data.Sqlite , což je jednoduchý poskytovatel ADO.NET pro SQLite. Microsoft.Data.Sqlite implementuje běžné ADO.NET abstrakce funkcí, jako jsou připojení, příkazy a čtečky dat.

Instalace balíčku NuGet SQLite

Pomocí správce balíčků NuGet vyhledejte balíček sqlite-net-pcl a přidejte nejnovější verzi do projektu aplikace .NET MAUI.

Existuje několik balíčků NuGet s podobnými názvy. Správný balíček má tyto atributy:

  • ID: sqlite-net-pcl
  • Autoři: SQLite-net
  • Vlastníci: praeclarum
  • Odkaz NuGet: sqlite-net-pcl

I přes název balíčku použijte balíček NuGet sqlite-net-pcl v projektech .NET MAUI.

Důležité

SQLite.NET je knihovna třetí strany podporovaná z úložiště praeclarum/sqlite-net.

Instalace SQLitePCLRaw.bundle_green

Kromě sqlite-net-pcl je nutné dočasně nainstalovat základní závislost, která zveřejňuje SQLite na každé platformě:

  • ID: SQLitePCLRaw.bundle_green
  • Verze:>= 2.1.0
  • Autoři: Eric Sink
  • Vlastníci: Eric Sink
  • Odkaz NuGet:SQLitePCLRaw.bundle_green

Konfigurace konstant aplikací

Konfigurační data, jako je název souboru databáze a cesta, se dají v aplikaci uložit jako konstanty. Ukázkový projekt obsahuje soubor Constants.cs , který poskytuje běžná konfigurační data:

public static class Constants
{
    public const string DatabaseFilename = "TodoSQLite.db3";

    public const SQLite.SQLiteOpenFlags Flags =
        // open the database in read/write mode
        SQLite.SQLiteOpenFlags.ReadWrite |
        // create the database if it doesn't exist
        SQLite.SQLiteOpenFlags.Create |
        // enable multi-threaded database access
        SQLite.SQLiteOpenFlags.SharedCache;

    public static string DatabasePath =>
        Path.Combine(FileSystem.AppDataDirectory, DatabaseFilename);
}

V tomto příkladu soubor konstant určuje výchozí SQLiteOpenFlag hodnoty výčtu, které se používají k inicializaci připojení k databázi. Výčet SQLiteOpenFlag podporuje tyto hodnoty:

  • Create: Připojení automaticky vytvoří soubor databáze, pokud neexistuje.
  • FullMutex: Připojení se otevře v režimu serializovaného podprocesu.
  • NoMutex: Připojení se otevře v režimu více vláken.
  • PrivateCache: Připojení se nebude účastnit sdílené mezipaměti, i když je povolené.
  • ReadWrite: Připojení může číst a zapisovat data.
  • SharedCache: Připojení se bude účastnit sdílené mezipaměti, pokud je povolená.
  • ProtectionComplete: Soubor je zašifrovaný a nepřístupný, když je zařízení zamknuté.
  • ProtectionCompleteUnlessOpen: Soubor se zašifruje, dokud se neotevře, ale bude přístupný i v případě, že uživatel zařízení zamkne.
  • ProtectionCompleteUntilFirstUserAuthentication: Soubor se zašifruje, dokud uživatel zařízení nespustí a odemkne.
  • ProtectionNone: Soubor databáze není zašifrovaný.

V závislosti na způsobu použití databáze možná budete muset zadat různé příznaky. Další informace o SQLiteOpenFlagstom, viz Otevření nové databáze Připojení ion v sqlite.org.

Vytvoření třídy přístupu k databázi

Třída obálky databáze abstrahuje vrstvu přístupu k datům ze zbytku aplikace. Tato třída centralizuje logiku dotazů a zjednodušuje správu inicializace databáze, což usnadňuje refaktoring nebo rozšíření operací s daty při růstu aplikace. Ukázková aplikace pro tento účel definuje TodoItemDatabase třídu.

Opožděná inicializace

Pomocí TodoItemDatabase asynchronní opožděné inicializace zpozdí inicializaci databáze, dokud nebude poprvé přístupná, s jednoduchou Init metodou, která se volá každou metodou ve třídě:

public class TodoItemDatabase
{
    SQLiteAsyncConnection Database;

    public TodoItemDatabase()
    {
    }

    async Task Init()
    {
        if (Database is not null)
            return;

        Database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);
        var result = await Database.CreateTableAsync<TodoItem>();
    }
    ...
}

Metody manipulace s daty

Třída TodoItemDatabase obsahuje metody pro čtyři typy manipulace s daty: vytvoření, čtení, úpravy a odstranění. Knihovna SQLite.NET poskytuje jednoduchou relační mapu objektů (ORM), která umožňuje ukládat a načítat objekty bez psaní příkazů SQL.

Následující příklad ukazuje metody manipulace s daty v ukázkové aplikaci:

public class TodoItemDatabase
{
    ...
    public async Task<List<TodoItem>> GetItemsAsync()
    {
        await Init();
        return await Database.Table<TodoItem>().ToListAsync();
    }

    public async Task<List<TodoItem>> GetItemsNotDoneAsync()
    {
        await Init();
        return await Database.Table<TodoItem>().Where(t => t.Done).ToListAsync();

        // SQL queries are also possible
        //return await Database.QueryAsync<TodoItem>("SELECT * FROM [TodoItem] WHERE [Done] = 0");
    }

    public async Task<TodoItem> GetItemAsync(int id)
    {
        await Init();
        return await Database.Table<TodoItem>().Where(i => i.ID == id).FirstOrDefaultAsync();
    }

    public async Task<int> SaveItemAsync(TodoItem item)
    {
        await Init();
        if (item.ID != 0)
            return await Database.UpdateAsync(item);
        else
            return await Database.InsertAsync(item);
    }

    public async Task<int> DeleteItemAsync(TodoItem item)
    {
        await Init();
        return await Database.DeleteAsync(item);
    }
}

Přístup k datům

Pokud TodoItemDatabase používáte injektáž závislostí, můžete třídu zaregistrovat jako jednoúčelový objekt, který lze použít v celé aplikaci. Stránky a třídu přístupu k databázi můžete například zaregistrovat jako služby v objektu IServiceCollection , v MauiProgram.cs a AddSingletonAddTransient metodách:

builder.Services.AddSingleton<TodoListPage>();
builder.Services.AddTransient<TodoItemPage>();

builder.Services.AddSingleton<TodoItemDatabase>();

Tyto služby se pak dají automaticky vložit do konstruktorů tříd a přistupovat k těmto službám:

TodoItemDatabase database;

public TodoItemPage(TodoItemDatabase todoItemDatabase)
{
    InitializeComponent();
    database = todoItemDatabase;
}

async void OnSaveClicked(object sender, EventArgs e)
{
    if (string.IsNullOrWhiteSpace(Item.Name))
    {
        await DisplayAlert("Name Required", "Please enter a name for the todo item.", "OK");
        return;
    }

    await database.SaveItemAsync(Item);
    await Shell.Current.GoToAsync("..");
}

Alternativně je možné vytvořit nové instance třídy přístupu k databázi:

TodoItemDatabase database;

public TodoItemPage()
{
    InitializeComponent();
    database = new TodoItemDatabase();
}

Další informace o injektáži závislostí v aplikacích .NET MAUI najdete v tématu Injektáž závislostí.

Rozšířená konfigurace

SQLite poskytuje robustní rozhraní API s více funkcemi, než je popsáno v tomto článku a ukázkové aplikaci. Následující části se týkají funkcí, které jsou důležité pro škálovatelnost.

Další informace najdete v dokumentaci KQLite na sqlite.org.

Protokolování před zápisem

Ve výchozím nastavení používá SQLite tradiční deník vrácení zpět. Kopie nezměněného obsahu databáze se zapíše do samostatného souboru vrácení zpět a změny se zapíšou přímo do souboru databáze. Potvrzení nastane při odstranění deníku vrácení zpět.

Protokolování před zápisem (WAL) zapisuje změny do samostatného souboru WAL. V režimu WAL je commit speciální záznam, připojený k souboru WAL, který umožňuje více transakcí nastat v jednom souboru WAL. Soubor WAL se sloučí zpět do databázového souboru ve speciální operaci označované jako kontrolní bod.

Wal může být rychlejší pro místní databáze, protože čtenáři a zapisovače navzájem neblokují, což umožňuje souběžné operace čtení a zápisu. Režim WAL ale neumožňuje změny velikosti stránky, přidá do databáze další přidružení souborů a přidá další operaci vytváření kontrolních bodů.

Pokud chcete v SQLite.NET povolit WAL, zavolejte EnableWriteAheadLoggingAsync metodu v SQLiteAsyncConnection instanci:

await Database.EnableWriteAheadLoggingAsync();

Další informace najdete v tématu SQLite Write-Ahead Logging on sqlite.org.

Kopírování databáze

Existuje několik případů, kdy může být nutné zkopírovat databázi SQLite:

  • Databáze byla dodána s vaší aplikací, ale musí být zkopírována nebo přesunuta do zapisovatelného úložiště na mobilním zařízení.
  • Potřebujete vytvořit zálohu nebo kopii databáze.
  • Potřebujete vytvořit verzi, přesunout nebo přejmenovat soubor databáze.

Obecně platí, že přesouvání, přejmenování nebo kopírování souboru databáze je stejný proces jako jakýkoli jiný typ souboru s několika dalšími aspekty:

  • Před pokusem o přesunutí souboru databáze by se měla zavřít všechna připojení k databázi.
  • Pokud použijete protokolování s předstihem, SQLite vytvoří soubor sdíleného přístupu k paměti (.shm) a (zapsat hlavičkový protokol) (.wal). Ujistěte se, že u těchto souborů použijete také všechny změny.