I have this piece of code and I don't even know how to initialize it at this point. I tried a few different versions but all of them come up with a warning saying
"Warning CS0649 Field 'NoteService.db' is never assigned to, and will always have its default value null"
The part where I try to create this table looks like this:
static SQLiteAsyncConnection db;
static async Task Init()
{
if (db != null)
return;
{
var databasePath = Path.Combine(FileSystem.AppDataDirectory, "MyData.db");
db = new SQLiteAsyncConnection(databasePath);
await db.CreateTableAsync<Note>();
}
}
This is the entirety of the code
MyNoteViewModel.cs:
namespace MyApp.ViewModels {
public class MyNoteViewModel : ViewModelBase
{
public ObservableRangeCollection<Note> Note { get;}
public AsyncCommand RefreshCommand { get; }
public AsyncCommand AddCommand { get; }
public AsyncCommand<Note> RemoveCommand { get; }
public new bool IsBusy { get; private set; }
public MyNoteViewModel()
{
Note = new ObservableRangeCollection<Note>();
RefreshCommand = new AsyncCommand(Refresh);
AddCommand = new AsyncCommand(Add);
RemoveCommand = new AsyncCommand<Note>(Remove);
}
async Task Add()
{
var name = await App.Current.MainPage.DisplayPromptAsync("Notes", "Enter your notes here");
await NoteService.AddNote(name);
await Refresh();
}
async Task Remove(Note note)
{
await NoteService.RemoveNote(note.Id);
await Refresh();
}
async Task Refresh()
{
IsBusy = true;
await Task.Delay(2000);
Note.Clear();
var notes = NoteService.GetNote();
Note.AddRange((IEnumerable<Note>)notes);
IsBusy = false;
return;
}
NotePage.xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:model="clr-namespace:MyApp.Models"
xmlns:mvvm="clr-namespace:MvvmHelpers;assembly=MvvmHelpers"
xmlns:viewmodels="clr-namespace:MyApp.ViewModels"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
x:Class="MyApp.MyNotePage"
x:Name="MyNotePage"
x:DataType="viewmodels:MyNoteViewModel"
BackgroundColor="White">
<ContentPage.BindingContext>
<viewmodels:MyNoteViewModel/>
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<xct:ItemSelectedEventArgsConverter x:Key="ItemSelectedEventArgsConverter"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.ToolbarItems>
<ToolbarItem Text="Add" Command="{Binding AddCommand}"/>
</ContentPage.ToolbarItems>
<ListView
BackgroundColor="Transparent"
CachingStrategy="RecycleElement"
HasUnevenRows="True"
IsPullToRefreshEnabled="True"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
ItemsSource="{Binding Note}"
RefreshCommand="{Binding RefreshCommand}"
RefreshControlColor="DarkViolet"
SelectionMode="None"
SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:Note">
<ViewCell>
<ViewCell.ContextActions>
<MenuItem
Command="{Binding Source={x:Reference MyNotePage}, Path=BindingContext.RemoveCommand}"
CommandParameter="{Binding .}"
IsDestructive="True"
Text="Delete"/>
</ViewCell.ContextActions>
<Grid Padding="10">
<Frame CornerRadius="20" HasShadow="True">
<StackLayout Orientation="Horizontal">
<StackLayout VerticalOptions="Center">
<Label
FontSize="Large"
Text="{Binding Name}"
VerticalOptions="Center"/>
<Label
FontSize="Small"
Text="{Binding Id}"
VerticalOptions="Center"/>
</StackLayout>
</StackLayout>
</Frame>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
NotePage.xaml.cs:
namespace MyApp
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MyNotePage
{
public MyNotePage()
{
InitializeComponent();
}
}
}
NoteService.cs:
namespace MyApp.Services
{
public static class NoteService
{
static SQLiteAsyncConnection db;
static async Task Init()
{
if (db != null)
return;
{
var databasePath = Path.Combine(FileSystem.AppDataDirectory, "MyData.db");
db = new SQLiteAsyncConnection(databasePath);
await db.CreateTableAsync<Note>();
}
}
public static async Task AddNote(string name)
{
await Init();
var note = new Note()
{
Name = name,
};
var id = await db.InsertAsync(note);
}
public static async Task RemoveNote(int id)
{
await Init();
await db.DeleteAsync<Note>(id);
}
public static async Task<IEnumerable<Note>> GetNote()
{
await Init();
var note = await db.Table<Note>().ToListAsync();
return note;
}
}
}
CodePudding user response:
GetNote
is async
, but you are not using await
when calling it. That means that notes
is a Task
. Then when you attempt to cast it, the cast fails and returns null, which then causes a NullRef
exception
var notes = NoteService.GetNote();
Note.AddRange((IEnumerable<Note>)notes);
instead do this
var notes = await NoteService.GetNote();
Note.AddRange(notes);
CodePudding user response:
var db = new SQLiteAsyncConnection(databasePath);
You are creating a new field scoped to the method, which is allowed by the compiler, but not what you want. Remove the var
keyword to reference your class-level field.