Xamarin.Forms Yerel Veritabanları

SQLite veritabanı altyapısı, uygulamaların paylaşılan koddaki veri nesnelerini yüklemesine ve kaydetmesine olanak tanır Xamarin.Forms . Örnek uygulama, yapılacaklar öğelerini depolamak için bir SQLite veritabanı tablosu kullanır. Bu makalede, bilgileri yerel veritabanında depolamak ve almak için paylaşılan kodda SQLite.Net nasıl kullanılacağı açıklanmaktadır.

iOS ve Android'de Todolist uygulamasının ekran görüntüleri

Aşağıdaki adımları izleyerek SQLite.NET mobil uygulamalarla tümleştirin:

  1. NuGet paketini yükleyin.
  2. Sabitleri yapılandırın.
  3. Veritabanı erişim sınıfı oluşturun.
  4. içindeki verilere erişin Xamarin.Forms.
  5. Gelişmiş yapılandırma.

SQLite NuGet paketini yükleme

NuGet paket yöneticisini kullanarak sqlite-net-pcl araması yapıp paylaşılan kod projesine en son sürümü ekleyin.

Benzer ada sahip birden fazla NuGet paketi olabilir. Doğru paketi şu özelliklerle ayırt edebilirsiniz:

  • Kimlik: sqlite-net-pcl
  • Yazarlar: SQLite-net
  • Sahipler: praeclarum
  • NuGet bağlantısı: sqlite-net-pcl

Paket adına rağmen, .NET Standard projelerinde bile sqlite-net-pcl NuGet paketini kullanın.

Önemli

SQLite.NET, praeclarum/sqlite-net deposunda desteklenen bir üçüncü taraf kitaplığıdır.

Uygulama sabitlerini yapılandırma

Örnek proje, ortak yapılandırma verileri sağlayan bir Constants.cs dosyası içerir:

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
    {
        get
        {
            var basePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            return Path.Combine(basePath, DatabaseFilename);
        }
    }
}

Sabitler dosyası, veritabanı bağlantısını başlatmak için kullanılan varsayılan SQLiteOpenFlag sabit listesi değerlerini belirtir. sabit SQLiteOpenFlag listesi şu değerleri destekler:

  • Create: Bağlantı, yoksa veritabanı dosyasını otomatik olarak oluşturur.
  • FullMutex: Bağlantı serileştirilmiş iş parçacığı modunda açılır.
  • NoMutex: Bağlantı çok iş parçacıklı modda açılır.
  • PrivateCache: Bağlantı, etkin olsa bile paylaşılan önbelleğe katılmaz.
  • ReadWrite: Bağlantı verileri okuyabilir ve yazabilir.
  • SharedCache: Bağlantı, etkinse paylaşılan önbelleğe katılır.
  • ProtectionComplete: Cihaz kilitliyken dosya şifrelenir ve erişilemez.
  • ProtectionCompleteUnlessOpen: Dosya açılana kadar şifrelenir, ancak kullanıcı cihazı kilitlese bile erişilebilir.
  • ProtectionCompleteUntilFirstUserAuthentication: Kullanıcı önyüklenip cihazın kilidini açana kadar dosya şifrelenir.
  • ProtectionNone: Veritabanı dosyası şifrelenmez.

Veritabanınızın nasıl kullanılacağına bağlı olarak farklı bayraklar belirtmeniz gerekebilir. hakkında SQLiteOpenFlagsdaha fazla bilgi için bkz . sqlite.org'da Yeni Veritabanı Bağlantısı Açma.

Veritabanı erişim sınıfı oluşturma

Veritabanı sarmalayıcı sınıfı, veri erişim katmanını uygulamanın geri kalanından soyutlar. Bu sınıf sorgu mantığını merkezileştirir ve veritabanı başlatma yönetimini basitleştirerek uygulama büyüdükçe veri işlemlerini yeniden düzenlemeyi veya genişletmeyi kolaylaştırır. Todo uygulaması bu amaçla bir TodoItemDatabase sınıf tanımlar.

Yavaş başlatma

, TodoItemDatabase veritabanının başlatılmasını ilk erişilene kadar geciktirmek için özel AsyncLazy<T> sınıf tarafından temsil edilen zaman uyumsuz gecikmeli başlatmayı kullanır:

public class TodoItemDatabase
{
    static SQLiteAsyncConnection Database;

    public static readonly AsyncLazy<TodoItemDatabase> Instance = new AsyncLazy<TodoItemDatabase>(async () =>
    {
        var instance = new TodoItemDatabase();
        CreateTableResult result = await Database.CreateTableAsync<TodoItem>();
        return instance;
    });

    public TodoItemDatabase()
    {
        Database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);
    }

    //...
}

Instance Alan, henüz yoksa nesnenin veritabanı tablosunu oluşturmak için TodoItem kullanılır ve tekil olarak döndürürTodoItemDatabase. Instance türündeki AsyncLazy<TodoItemDatabase> alanı, ilk kez beklenildiğinde oluşturulur. Birden çok iş parçacığı aynı anda alana erişmeye çalışırsa, hepsi tek bir yapıyı kullanır. Ardından, inşaat tamamlandığında tüm await işlemler tamamlar. Ayrıca, inşaat tamamlandıktan sonraki tüm await işlemler, değer mevcut olduğundan hemen devam ediyor.

Not

Veritabanı bağlantısı, uygulamanın ömrü boyunca tek bir veritabanı bağlantısının kullanılmasını sağlayan statik bir alandır. Kalıcı, statik bağlantı kullanmak, tek bir uygulama oturumu sırasında bağlantıları birden çok kez açıp kapatmaktan daha iyi performans sunar.

Zaman uyumsuz gecikmeli başlatma

Veritabanı başlatmayı başlatmak, yürütmeyi engellemekten kaçınmak ve özel durumları yakalama fırsatına sahip olmak için örnek uygulama, sınıfı tarafından AsyncLazy<T> temsil edilen zaman uyumsuz yavaş başlatmayı kullanır:

public class AsyncLazy<T>
{
    readonly Lazy<Task<T>> instance;

    public AsyncLazy(Func<T> factory)
    {
        instance = new Lazy<Task<T>>(() => Task.Run(factory));
    }

    public AsyncLazy(Func<Task<T>> factory)
    {
        instance = new Lazy<Task<T>>(() => Task.Run(factory));
    }

    public TaskAwaiter<T> GetAwaiter()
    {
        return instance.Value.GetAwaiter();
    }
}

sınıfı AsyncLazy ve Task<T> türlerini birleştirerek kaynağın Lazy<T> başlatılmasını temsil eden yavaş başlatılan bir görev oluşturur. Oluşturucuya geçirilen fabrika temsilcisi zaman uyumlu veya zaman uyumsuz olabilir. Fabrika temsilcileri bir iş parçacığı havuzu iş parçacığında çalışır ve birden çok kez yürütülmeyecektir (birden çok iş parçacığı bunları aynı anda başlatmayı denese bile). Bir fabrika temsilcisi tamamlandığında, yavaş başlatılan değer kullanılabilir ve örneği bekleyen AsyncLazy<T> tüm yöntemler değeri alır. Daha fazla bilgi için bkz . AsyncLazy.

Veri işleme yöntemleri

sınıfı dört TodoItemDatabase veri işleme türü için yöntemler içerir: oluşturma, okuma, düzenleme ve silme. SQLite.NET kitaplığı, SQL deyimleri yazmadan nesneleri depolamanıza ve almanıza olanak tanıyan basit bir Nesne İlişkisel Eşlemesi (ORM) sağlar.

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

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

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

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

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

'da verilere erişme Xamarin.Forms

sınıfı TodoItemDatabase , sınıfındaki Instance veri erişim işlemlerinin TodoItemDatabase çağrılabildiği alanı kullanıma sunar:

async void OnSaveClicked(object sender, EventArgs e)
{
    var todoItem = (TodoItem)BindingContext;
    TodoItemDatabase database = await TodoItemDatabase.Instance;
    await database.SaveItemAsync(todoItem);

    // Navigate backwards
    await Navigation.PopAsync();
}

Gelişmiş yapılandırma

SQLite, bu makalede ve örnek uygulamada ele alınandan daha fazla özelliğe sahip sağlam bir API sağlar. Aşağıdaki bölümlerde ölçeklenebilirlik açısından önemli olan özellikler ele alınıyor.

Daha fazla bilgi için bkz . sqlite.org hakkında SQLite Belgeleri .

Önceden yazma günlüğü

Varsayılan olarak, SQLite geleneksel bir geri alma günlüğü kullanır. Değiştirilmemiş veritabanı içeriğinin bir kopyası ayrı bir geri alma dosyasına yazılır, ardından değişiklikler doğrudan veritabanı dosyasına yazılır. İŞLEME, geri alma günlüğü silindiğinde gerçekleşir.

Önceden Yazma Günlüğü (WAL), değişiklikleri önce ayrı bir WAL dosyasına yazar. WAL modunda COMMIT, WAL dosyasına eklenen ve tek bir WAL dosyasında birden çok işlemin gerçekleşmesini sağlayan özel bir kayıttır. WAL dosyası, denetim noktası olarak adlandırılan özel bir işlemde veritabanı dosyasıyla yeniden birleştirilir.

Okuyucular ve yazarlar birbirini engellemediğinden ve okuma ve yazma işlemlerinin eşzamanlı olmasını sağladığından WAL yerel veritabanları için daha hızlı olabilir. Ancak WAL modu sayfa boyutunda değişikliklere izin vermez, veritabanına ek dosya ilişkilendirmeleri ekler ve ek denetim noktası oluşturma işlemini ekler.

SQLite.NET'da WAL'yi etkinleştirmek için örnekte yöntemini çağırın EnableWriteAheadLoggingAsync SQLiteAsyncConnection :

await Database.EnableWriteAheadLoggingAsync();

Daha fazla bilgi için bkz . sqlite.org'da SQLite Önceden Yazma Günlüğünü Kaydetme .

Veritabanı kopyalama

SQLite veritabanını kopyalamanın gerekebileceği birkaç durum vardır:

  • Veritabanı uygulamanızla birlikte gönderildi, ancak mobil cihazda kopyalanması veya yazılabilir depolama alanına taşınması gerekir.
  • Veritabanının yedeğini veya kopyasını oluşturmanız gerekir.
  • Veritabanı dosyasını sürüm, taşıma veya yeniden adlandırmanız gerekir.

Genel olarak, veritabanı dosyasını taşımak, yeniden adlandırmak veya kopyalamak, diğer dosya türleriyle aynı işlemdir ve dikkate alınması gereken birkaç nokta vardır:

  • Veritabanı dosyasını taşımaya çalışmadan önce tüm veritabanı bağlantıları kapatılmalıdır.
  • Önceden Yazma Günlüğü kullanıyorsanız, SQLite bir Paylaşılan Bellek Erişimi (.shm) dosyası ve bir (Önceden Yazma Günlüğü) (.wal) dosyası oluşturur. Bu dosyalara da tüm değişiklikleri uyguladığınıza emin olun.

Daha fazla bilgi için bkz . içinde Xamarin.FormsDosya İşleme.