Setup and Use SQLite with .NET MAUI - Tutorial and Code Examples
I was recently working on a .NET MAUI mobile app and needed some data to persist between launches. I know from experience that SQLite is a very common approach to storing data locally on mobile devices so I began implementing it. As usual, the road to success was bumpy and I hit an error immediately and wrote about fixing it fairly quickly in Using SQLite as a Local Database With .NET MAU (resolving missing SQLitePCLRaw.provider.dynamic_cdecl). This issue is a problem one would encounter when setting up the NuGet packages. This post was pretty small, so I decided to write this post on the entire process of setting up and using SQLite with .NET MAUI.
1) Install the SQLite NuGet packages
In order to use SQLite, you will need "sqlite-net-pcl" and "SQLitePCLRaw.provider.dynamic_cdecl."
I attempted to follow Microsoft's instructions and use "SQLitePCLRaw.bundle_green" in place of SQLitePCLRaw.provider.dynamic_cdecl" but I continued to get FileNotFoundExceptions. These are simply the NuGet packages that worked for me in the end and are still working.
2) Set up some simple database access methods.
I did follow Microsoft's instructions on this part. I found their example of Constants.cs to be really helpful. I found it better to use the Environment.SpecialFolder.Personal file path as the database file path. This one also seems to work quite nicely on my Android devices.
This is what I am using for mine.
public static class Constants { public const string DatabaseFilename = "todo.db"; 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(Environment.GetFolderPath(Environment.SpecialFolder.Personal), DatabaseFilename); }
public static async void CreateDatabase() { try { var database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags); var result = await database.CreateTableAsync<Todo>(); } catch (Exception ex) { // Eventually some logging, probably } }
public static async Task<int> AddTodo(Todo todoItem) { try { var database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags); return await database.InsertAsync(todoItem); } catch (Exception ex) { return -1; } } public static async Task<Todo> GetLatestTodo() { try { var database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags); var todos = await database.Table<Todo>().ToListAsync(); return todos.OrderBy(b => b.CreateDate).FirstOrDefault(); } catch (Exception ex) { return new Todo(); } }
await Database.QueryAsync<TodoItem>("SELECT * FROM [TodoItem] WHERE [Done] = 0");
public class Todo { [PrimaryKey, AutoIncrement] public int ID { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public DateTime CreateDate { get { return DateTime.Now; } } public string TaskName { get; set; } public string TaskDetails { get; set; } } }
public bool WithinDataRange { get { return (DateTime.Now > StartDate) && (DateTime.Now < EndDate); } }
[RelayCommand] internal async Task CreateTodo() { Todo todo = new() { StartDate = StartDate, EndDate = EndDate, TaskName = "Woah we could instead use input", TaskDetails = "Woah we could instead use input", }; var result = await TodoDatabase.AddTodo(todo); }
<Button x:Name="CreateBtn" Text="Create TODO" Command="{Binding CreateTodoCommand}" HorizontalOptions="Center" />
Comments
Post a Comment