Skip to content

Commit 07fcfcd

Browse files
Merge pull request #817 from unoplatform/dev/mazi/litedb-fix
2 parents 3c59719 + 2343510 commit 07fcfcd

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

UI/LiteDB/LiteDB/LiteDB.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ Of course we simplify here a bit. On top we most probable have a unique identifi
6767

6868
![Comparison](Comparison.png)
6969

70-
## LiteDB and UNO
71-
Now we can use this power when we want to build a **UNO Platform** app. You might remember that we already could do something similiar with SQLite: *[Working with SQLite and WebAssembly for .NET Developers](https://platform.uno/blog/working-with-sqlite-and-webassembly-for-net-developers/)*. This article describes how to use SQLite with the UNO Platform. And guess what: We can do something similiar with **LiteDB** as well. So let's do it. If you did not setup the **UNO Platform** on your developer machine, head first to the [*Get Started* ](https://platform.uno/docs/articles/get-started.html)guide. Yes you read right, we can also use **LiteDB** inside the browser and therefore give the user an easy possibility to perist state! That is awesome! Here is what we are going for:
70+
## LiteDB and Uno Platform
71+
Now we can use this power when we want to build a **Uno Platform** app. You might remember that we already could do something similiar with SQLite: *[Working with SQLite and WebAssembly for .NET Developers](https://platform.uno/blog/working-with-sqlite-and-webassembly-for-net-developers/)*. This article describes how to use SQLite with the Uno Platform. And guess what: We can do something similiar with **LiteDB** as well. So let's do it. If you did not setup the **Uno Platform** on your developer machine, head first to the [*Get Started* ](https://platform.uno/docs/articles/get-started.html)guide. Yes you read right, we can also use **LiteDB** inside the browser and therefore give the user an easy possibility to perist state! That is awesome! Here is what we are going for:
7272

7373
![LiteDB WASM](Browser.png)
7474

75-
So let's create a new UNO Platform app. I am a big fan of the command line arguments, but you can also take the [Visual Studio Project templates](https://platform.uno/docs/articles/get-started-dotnet-new.html). To create a new app you can simply type: `dotnet new unoapp-uwp-net6 -o LiteDBSample` (the template allows also for optionally removing some UNO Platform heads: `dotnet new unoapp-uwp-net6 -o LiteDBSample -M=false -skia-wpf=false -skia-gtk=false -skia-linux-fb=false`. With this you are only running the WASM head). Don't worry you can also take other templates if you wish, as the code will work everywhere. Now if we want to use **LiteDB**, we have to reference the nuget package in your UNO Head<sup>[What is a Head?](https://platform.uno/docs/articles/uno-app-solution-structure.html)</sup> projects:
75+
So let's create a new Uno Platform app. I am a big fan of the command line arguments, but you can also take the [Visual Studio Project templates](https://platform.uno/docs/articles/get-started-dotnet-new.html). To create a new app you can simply type: `dotnet new unoapp-uwp-net6 -o LiteDBSample` (the template allows also for optionally removing some Uno Platform heads: `dotnet new unoapp-uwp-net6 -o LiteDBSample -M=false -skia-wpf=false -skia-gtk=false -skia-linux-fb=false`. With this you are only running the WASM head). Don't worry you can also take other templates if you wish, as the code will work everywhere. Now if we want to use **LiteDB**, we have to reference the nuget package in your Uno Platform Head<sup>[What is a Head?](https://platform.uno/docs/articles/uno-app-solution-structure.html)</sup> projects:
7676

7777
```csharp
7878
dotnet add package LiteDB --version 5.0.15
@@ -145,7 +145,20 @@ var itemsWhichShouldBeDoneByToday =
145145
where !item.IsDone && item.DeadLine <= DateTime.Now
146146
select item).ToList();
147147
```
148-
Of course you can also use the method chaining instead of the query language. The core idea is, that `Query()` returns you a `IQueryable`, which let's you use all the power of LINQ and friends. And there you have it, the easy and rapid power of **LiteDB** paired with the easiness and power of the **UNO Platform**.
148+
Of course you can also use the method chaining instead of the query language. The core idea is, that `Query()` returns you a `IQueryable`, which let's you use all the power of LINQ and friends. And there you have it, the easy and rapid power of **LiteDB** paired with the easiness and power of the **Uno Platform**.
149+
150+
## File System Initialization on WebAssembly
151+
152+
On WebAssembly, the file system is initialized asynchronously while the application is launching. Attempts to access the file system before this operation finalizes (e.g. during `Application.OnLaunched` or while the main page of the application is navigated to) may have unexpected results and could even cause a crash.
153+
154+
To prevent this, make sure to perform and await an asynchronous operation on `ApplicationData.Current.LocalFolder` first. A good example would be to store the database in a nested `Data` folder, which needs to be asynchronously created first:
155+
156+
```csharp
157+
var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
158+
var dataFolder = await localFolder.CreateFolderAsync("Data", CreationCollisionOption.OpenIfExists);
159+
var dbPath = System.IO.Path.Combine(dataFolder.Path, "save.db");
160+
var liteDb = new LiteDatabase(dbPath);
161+
```
149162

150163
## LiteDB `async`
151164
One thing you might have noticed until now: All the methods I used are **synchrnous**. There is no `await liteDatabase.GetCollection<TodoItem>().ToListAsync()` or friends. You should consider the asynchrnous paradigm. If you have a regular desktop application or even the WASM head, `async` makes sense, as it doesn't block the UI thread. **LiteDB** itself doesn't offer asynchrnous operations, but there is a community project, which does that: [litedb-async](https://github.com/mlockett42/litedb-async).

UI/LiteDB/LiteDB/src/LiteDBSample.Shared/MainPage.xaml.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Microsoft.UI.Xaml;
66
using Microsoft.UI.Xaml.Controls;
77
using LiteDB;
8+
using Microsoft.UI.Xaml.Navigation;
89

910
namespace LiteDBSample
1011
{
@@ -21,7 +22,20 @@ public MainPage()
2122
_todoItems = new ObservableCollection<TodoItem>();
2223
}
2324

24-
private LiteDatabase _liteDatabase;
25+
protected override async void OnNavigatedTo(NavigationEventArgs e)
26+
{
27+
base.OnNavigatedTo(e);
28+
29+
// Before the database is accessed for the first time on WASM, the filesystem needs to be
30+
// initialized, otherwise data might be lost. Ensure that any asynchronous operation is
31+
// awaited before creating/accessing the database, as await will wait for the initialization to complete.
32+
// See https://platform.uno/docs/articles/features/file-management.html#webassembly-file-system for more information.
33+
var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
34+
var data = await localFolder.CreateFolderAsync("Data", CreationCollisionOption.OpenIfExists);
35+
LoadFromDatabase(this, null);
36+
}
37+
38+
private LiteDatabase _liteDatabase;
2539

2640
private LiteDatabase LiteDatabase
2741
{
@@ -36,7 +50,7 @@ private LiteDatabase LiteDatabase
3650
}
3751
}
3852

39-
private static string DbPath => System.IO.Path.Combine(ApplicationData.Current.LocalFolder.Path, "save.db");
53+
private static string DbPath => System.IO.Path.Combine(ApplicationData.Current.LocalFolder.Path, "Data", "save.db");
4054

4155
private void LoadFromDatabase(object sender, RoutedEventArgs args)
4256
{

0 commit comments

Comments
 (0)