Previous MAUI-with-SQLite MAUI-SQLite-CRUD Next

SQLite Basics in .NET MAUI - Step-by-Step Checklist Tutorial

SQLite basics in .NET MAUI into a step-by-step checklist tutorial you can follow while coding. This way, you’ll have a clear roadmap from setup to CRUD operations.

📝 Step-by-Step Tutorial: SQLite in MAUI

Step 1. Install NuGet Package

Add sqlite-net-pcl to your MAUI project.

This gives you async SQLite support with simple ORM features.

dotnet add package sqlite-net-pcl

Step 2. Create Your Data Model

Define a class with attributes for SQLite mapping.

using SQLite;

public class TodoItem
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }

    [MaxLength(250)]
    public string Name { get; set; }

    public bool IsCompleted { get; set; }
}

Step 3. Build a Database Service

Encapsulate database logic in a helper class.

public class DatabaseService
{
    readonly SQLiteAsyncConnection _database;

    public DatabaseService(string dbPath)
    {
        _database = new SQLiteAsyncConnection(dbPath);
        _database.CreateTableAsync<TodoItem>().Wait();
    }

    public Task<List<TodoItem>> GetItemsAsync() =>
        _database.Table<TodoItem>().ToListAsync();

    public Task<int> SaveItemAsync(TodoItem item) =>
        _database.InsertOrReplaceAsync(item);

    public Task<int> DeleteItemAsync(TodoItem item) =>
        _database.DeleteAsync(item);
}

Step 4. Configure Database Path

Store the .db3 file in the app’s data directory.

string dbPath = Path.Combine(FileSystem.AppDataDirectory, "mydb.db3");
var db = new DatabaseService(dbPath);

Step 5. Connect to Your UI

Bind a CollectionView or ListView to GetItemsAsync().

Add buttons or swipe gestures for Add / Update / Delete.

Example (simplified):

<CollectionView ItemsSource="{Binding Items}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <StackLayout Orientation="Horizontal">
                <Label Text="{Binding Name}" />
                <CheckBox IsChecked="{Binding IsCompleted}" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Step 6. Use Dependency Injection (Optional)

Register DatabaseService in MauiProgram.cs:

builder.Services.AddSingleton<DatabaseService>(
    s => new DatabaseService(
        Path.Combine(FileSystem.AppDataDirectory, "mydb.db3")));

Inject it into your ViewModels for clean architecture.

✅ Checklist Recap

  • Install sqlite-net-pcl.
  • Create your model class.
  • Build a DatabaseService.
  • Configure database path.
  • Bind data to UI.
  • (Optional) Add DI for scalability.

MAUI SQLite Sample Project Structure

A ready-made sample project structure you can drop into your MAUI solution. This will give you a clean architecture with folders for Models, Services, ViewModels, and Views, all wired up to SQLite.

📁 Project Structure

MyMauiApp/
│
├── Models/
│   └── TodoItem.cs
│
├── Services/
│   └── DatabaseService.cs
│
├── ViewModels/
│   └── TodoViewModel.cs
│
├── Views/
│   └── TodoPage.xaml
│   └── TodoPage.xaml.cs
│
├── MauiProgram.cs
└── App.xaml / App.xaml.cs

🧩 Code Walkthrough

1. Models/TodoItem.cs

using SQLite;

namespace MyMauiApp.Models;

public class TodoItem
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }

    [MaxLength(250)]
    public string Name { get; set; }

    public bool IsCompleted { get; set; }
}

2. Services/DatabaseService.cs

using SQLite;
using MyMauiApp.Models;

namespace MyMauiApp.Services;

public class DatabaseService
{
    readonly SQLiteAsyncConnection _database;

    public DatabaseService(string dbPath)
    {
        _database = new SQLiteAsyncConnection(dbPath);
        _database.CreateTableAsync<TodoItem>().Wait();
    }

    public Task<List<TodoItem>> GetItemsAsync() =>
        _database.Table<TodoItem>().ToListAsync();

    public Task<int> SaveItemAsync(TodoItem item) =>
        _database.InsertOrReplaceAsync(item);

    public Task<int> DeleteItemAsync(TodoItem item) =>
        _database.DeleteAsync(item);
}

3. ViewModels/TodoViewModel.cs

using System.Collections.ObjectModel;
using MyMauiApp.Models;
using MyMauiApp.Services;

namespace MyMauiApp.ViewModels;

public class TodoViewModel : BindableObject
{
    private readonly DatabaseService _db;

    public ObservableCollection<TodoItem> Items { get; } = new();

    public TodoViewModel(DatabaseService db)
    {
        _db = db;
        LoadItems();
    }

    private async void LoadItems()
    {
        var items = await _db.GetItemsAsync();
        Items.Clear();
        foreach (var item in items)
            Items.Add(item);
    }

    public async Task AddItem(string name)
    {
        var newItem = new TodoItem { Name = name, IsCompleted = false };
        await _db.SaveItemAsync(newItem);
        LoadItems();
    }

    public async Task ToggleItem(TodoItem item)
    {
        item.IsCompleted = !item.IsCompleted;
        await _db.SaveItemAsync(item);
        LoadItems();
    }

    public async Task DeleteItem(TodoItem item)
    {
        await _db.DeleteItemAsync(item);
        LoadItems();
    }
}

4. Views/TodoPage.xaml

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             x:Class="MyMauiApp.Views.TodoPage"
             Title="Todo List">

    <VerticalStackLayout Padding="20">
        <Entry x:Name="NewItemEntry" Placeholder="Enter new task..." />
        <Button Text="Add" Clicked="OnAddClicked" />

        <CollectionView ItemsSource="{Binding Items}">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout Orientation="Horizontal" Padding="5">
                        <Label Text="{Binding Name}" VerticalOptions="Center" />
                        <CheckBox IsChecked="{Binding IsCompleted}" />
                        <Button Text="Delete" CommandParameter="{Binding .}" />
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </VerticalStackLayout>
</ContentPage>

5. Views/TodoPage.xaml.cs

using MyMauiApp.ViewModels;
using MyMauiApp.Models;

namespace MyMauiApp.Views;

public partial class TodoPage : ContentPage
{
    private readonly TodoViewModel _vm;

    public TodoPage(TodoViewModel vm)
    {
        InitializeComponent();
        BindingContext = _vm = vm;
    }

    private async void OnAddClicked(object sender, EventArgs e)
    {
        if (!string.IsNullOrWhiteSpace(NewItemEntry.Text))
        {
            await _vm.AddItem(NewItemEntry.Text);
            NewItemEntry.Text = string.Empty;
        }
    }
}

6. MauiProgram.cs

using MyMauiApp.Services;
using MyMauiApp.ViewModels;
using MyMauiApp.Views;

namespace MyMauiApp;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();

        builder
            .UseMauiApp<App>();

        // Register DatabaseService
        builder.Services.AddSingleton<DatabaseService>(
            s => new DatabaseService(
                Path.Combine(FileSystem.AppDataDirectory, "mydb.db3")));

        // Register ViewModel
        builder.Services.AddTransient<TodoViewModel>();

        // Register Page
        builder.Services.AddTransient<TodoPage>();

        return builder.Build();
    }
}

🚀 How to Run

  • Add the NuGet package sqlite-net-pcl.
  • Copy this structure into your MAUI project.
  • Set TodoPage as your startup page in App.xaml.cs.
  • Run the app — you’ll have a working local SQLite-backed Todo list.
Back to Index
Previous MAUI-with-SQLite MAUI-SQLite-CRUD Next
*