You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI中SQLite-net-PCL的CreateTableAsync执行异常问题

问题:SQLiteAsyncConnection 操作异常导致表创建失败、ID不递增

我按教程实现MAUI应用后,遇到以下问题:

  • 调用db.CreateTableAsync<Restroom>时应用直接冻结,修复冻结后,该方法又完全失效,直接退出InitAsync和AddPinAsync任务
  • 同一运行时内多次执行AddPinAsync,首次执行时CreateTableAsync会中断;后续因db已初始化,会执行AddPinAsync剩余逻辑,但无论添加多少次数据,Restroom的Id都不会自动递增

Restroom.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);
    }
}

MainPage.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;
        }
    }
}

内容的提问来源于stack exchange,提问作者K_Ketchup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:44:55