.NET MAUI - SQLite-net-PCL CreateTableAsync 中断

问题描述 投票:0回答:1

我以前遇到过这个问题,在遵循本教程后,在 Service.cs 文件中调用 db.CreateTableAsync 之后,我的整个应用程序冻结了。使用 这个解决方案修复此问题后,应用程序停止冻结,但 CreateTableAsync 似乎可以什么都没有,只是中断了 Init 任务和 AddPin 任务。在同一运行时,如果我尝试多次运行 AddPin 任务,第一次 CreateTableAsync 将中断,并且在初始之后连续多次,将调用 AddPin 的其余部分(因为 db != null),值得注意的是无论我运行 AddPin 多少次,id 都不会增加。

厕所.cs

using SQLite; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Dook.Model { public class Restroom { [SQLite.PrimaryKey, SQLite.AutoIncrement] [Column("Id")] public int Id { get; set; } [Column("Name")] public string Name { get; set; } [Column("Address")] public string Address { get; set; } [Column("Username")] public string Username { get; set; } [Column("Location")] public Location PinLocation { get; set; } } }
RestroomService.cs

using Dook.Model; using SQLite; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Dook.Services { public static class RestroomService { static SQLiteAsyncConnection db; static async Task InitAsync() { if(db != null) return; var databasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyData.db"); db = new SQLiteAsyncConnection(databasePath); await db.CreateTableAsync<Restroom>(); Debug.WriteLine("Bruh"); } public static async Task AddPinAsync(string name, string address, string username, Location location) { await InitAsync(); var restroom = new Restroom { Name = name, Address = address, Username = username, PinLocation = location }; var id = await db.InsertAsync(restroom); } public static async Task RemovePinAsync(int id) { await InitAsync(); await db.DeleteAsync<Restroom>(id); } public static async Task<IEnumerable<Restroom>> GetPinAsync() { await InitAsync(); var restroom = await db.Table<Restroom>().ToListAsync(); return restroom; } } }
MainPage.xaml.cs

namespace Dook; using Microsoft.Maui.Controls.Maps; using Microsoft.Maui.Maps; using System.Diagnostics; using Map = Microsoft.Maui.Controls.Maps.Map; using Dook.ViewModel; using Dook.Model; public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); MoveMapLocation(); } private void GoToLocation_Button(object sender, EventArgs e) { MoveMapLocation(); } private void OnMapClicked(object sender, MapClickedEventArgs e) { var vm = (MainViewModel)this.BindingContext; if (vm.AddCommand.CanExecute(e.Location)) vm.AddCommand.ExecuteAsync(e.Location); } private void RefreshButton_Clicked(object sender, EventArgs e) { var vm = (MainViewModel)this.BindingContext; vm.RefreshCommand.ExecuteAsync(); } private void MoveMapLocation() { //Function to avoid boilerplate code MapSpan mapSpan = new MapSpan(MainViewModel.GetLocation(), 0.01, 0.01); mainmap.MoveToRegion(mapSpan); } }
主页.xaml

<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:viewmodel="clr-namespace:Dook.ViewModel" x:DataType="viewmodel:MainViewModel" xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.Maps" xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials" xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit" xmlns:model="clr-namespace:Dook.Model" x:Class="Dook.MainPage" Title="{Binding Title}" Shell.NavBarIsVisible="False"> <ContentPage.BindingContext> <viewmodel:MainViewModel /> </ContentPage.BindingContext> <Grid Margin="0" RowDefinitions="*, Auto" ColumnDefinitions="*"> <maps:Map x:Name="mainmap" MapType="Street" IsShowingUser="True" x:FieldModifier="public" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" IsVisible="True" IsEnabled="True" Grid.Row="0" MapClicked="OnMapClicked" ItemsSource="{Binding Restroom}"> <maps:Map.ItemTemplate> <DataTemplate x:DataType="model:Restroom"> <maps:Pin Label="{Binding Name}" Address="{Binding Address}" Type="Generic" Location="{Binding PinLocation}"/> </DataTemplate> </maps:Map.ItemTemplate> </maps:Map> <Button Text="Refresh" IsEnabled="{Binding IsNotBusy}" Clicked="RefreshButton_Clicked" Margin="5" VerticalOptions="Center" HorizontalOptions="Start" Grid.Row="1"/> <ImageButton Source="feather_navigation_icon.png" Aspect="AspectFill" Clicked="GoToLocation_Button" IsEnabled="{Binding IsNotBusy}" Margin="20" VerticalOptions="End" HorizontalOptions="End" WidthRequest="13" HeightRequest="13" BackgroundColor="Transparent" CornerRadius="10" Grid.Row="0"/> </Grid> </ContentPage>
MainViewModel.cs

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Maui.Controls.Maps; using Microsoft.Maui.Maps; using Map = Microsoft.Maui.Controls.Maps.Map; using Dook.Model; using Dook.Services; using MvvmHelpers; using MvvmHelpers.Commands; using CommunityToolkit.Maui.Core.Extensions; namespace Dook.ViewModel { public class MainViewModel : BaseViewModel { public ObservableRangeCollection<Restroom> Restroom { get; set; } public AsyncCommand RefreshCommand { get; } public AsyncCommand<Location> AddCommand { get; } public AsyncCommand<Restroom> RemoveCommand { get; } public MainViewModel() { Title = "Map Controller"; Restroom = new ObservableRangeCollection<Restroom>(); AddCommand = new AsyncCommand<Location>(AddAsync); RemoveCommand = new AsyncCommand<Restroom>(RemoveAsync); RefreshCommand = new AsyncCommand(RefreshAsync); } async Task AddAsync(Location currentLocation) { var name = await App.Current.MainPage.DisplayPromptAsync("Location Name", "Name of Location"); // var address = "Latitude: {pinlocation.Latitude}, Longitude: {pinlocation.Longitude}, Altitude: {location.Altitude}"; var address = "test"; var username = await App.Current.MainPage.DisplayPromptAsync("Username", "Username of Toilet Adder"); var location = currentLocation; if(name == null || address == null || username == null) { return; } await RestroomService.AddPinAsync(name, address, username, location); await RefreshAsync(); } async Task RemoveAsync(Restroom restroom) { await RestroomService.RemovePinAsync(restroom.Id); await RefreshAsync(); } async Task RefreshAsync() { IsBusy = true; await Task.Delay(2000); Restroom.Clear(); var restrooms = await RestroomService.GetPinAsync(); Restroom.AddRange(restrooms); IsBusy = false; } public static Location GetLocation() { try { Location location = new(); location = Geolocation.Default.GetLastKnownLocationAsync().Result; if (location != null) return location; } catch (Exception ex) { Debug.WriteLine($"Unable to get location: {ex.Message}"); Application.Current.MainPage.DisplayAlert("Error!", ex.Message, "OK"); } return null; } } }
    
c# sqlite xamarin maui sqlite-net
1个回答
0
投票
根据 Jason 的评论,作为答案:

将纬度和经度存储为单独的字段可以解决该问题。

© www.soinside.com 2019 - 2024. All rights reserved.