我的 .net maui 项目的 Data 文件夹中有一个名为 cbt.db 的数据库文件。我试图从此数据库中检索问题和答案的集合,但每当我运行该应用程序时,我都会在 QuizViewModel 中显示
var questions = await _dBService.GetQuestionsAsync();
的行上收到 System.NullReferenceException。
QuizViewModel.cs
namespace CBT.ViewModels;
public partial class QuizViewModel : ObservableObject
{
private IDBService _dBService;
private int _currentQuestionIndex = 1;
public ObservableCollection<Question> Questions { get; } = new();
[ObservableProperty]
public Question? currentQuestion;
public QuizViewModel(IDBService dBService)
{
_dBService = dBService;
}
[RelayCommand]
public static async Task<QuizViewModel> CreateAsync(IDBService dBService)
{
var viewModel = new QuizViewModel(dBService);
await viewModel.GetQuestionsAsync();
viewModel.CurrentQuestion = viewModel.Questions[viewModel._currentQuestionIndex];
return viewModel;
}
[RelayCommand]
async Task GetQuestionsAsync()
{
try
{
var questions = await _dBService.GetQuestionsAsync();
if (questions.Count != 0)
{
Questions.Clear();
}
foreach(var question in questions)
{
Questions.Add(question);
}
}
catch(Exception ex)
{
Debug.Print($"Unable to get questions: {ex.Message}");
}
}
// Other Methods go here...
}
DBService.cs
namespace CBT.Services;
class DBService : IDBService
{
private readonly SQLiteAsyncConnection _database;
public static string DBPath { get; } = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "cbt.db");
// The constructor initializes the database connection and creates the table if not exists
public DBService()
{
LoadDB();
_database = new SQLiteAsyncConnection(DBPath, Constants.Flags);
_database.CreateTableAsync<Question>();
}
public void LoadDB()
{
if (!File.Exists(DBPath))
{
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(App)).Assembly;
using Stream? stream = assembly.GetManifestResourceStream("CBT.Data.cbt.db");
using MemoryStream? memoryStream = new();
stream.CopyTo(memoryStream);
File.WriteAllBytes(DBPath, memoryStream.ToArray());
Debug.WriteLine($"{stream}");
}
}
public async Task<List<Question>> GetQuestionsAsync()
{
return await _database.Table<Question>().ToListAsync();
}
// Other CRUD Operations goes here
}
MauiProgram.cs
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder.Services.AddSingleton<IDBService, DBService>();
builder.Services.AddSingleton<INavigationService, NavigationService>();
builder.Services.AddTransient<QuizViewModel>();
builder.Services.AddTransient<QuizPage>();
return builder.Build();
}
}
我终于找到了解决办法。我在初始化之前调用了 DBService,因此我在 QuizPage 中初始化了 QuizViewModel 并将其传递给 DBService。这是它的样子。
测验页面.xaml.cs
public partial class QuizPage : ContentPage
{
private QuizViewModel _viewModel;
public QuizPage(QuizViewModel quizViewModel)
{
InitializeComponent();
InitializeViewModel();
}
private async void InitializeViewModel()
{
// Create an instance of IDBService
var dbService = new DBService();
// Create an instance of QuizViewModel using CreateAsync method
_viewModel = await QuizViewModel.CreateAsync(dbService);
BindingContext = _viewModel;
}
}