.NET MAUI中SQLite 3存储含List<T>的模型问题求助
问题分析与解决方案
一、"MyItemStorage表不存在" 异常原因及修复
首次删除表重启时出现该异常,核心问题是表创建顺序错误,且错误引入了多对多关系才需要的中间表MyItemStorageMyItems,干扰了ORM的表创建逻辑:
- OneToMany关系无需中间表,子表(MyItem)只需添加指向主表的外键字段即可。
- 表创建顺序必须先创建子表(MyItem),再创建主表(MyItemStorage),否则ORM处理主表的关联属性时,会找不到依赖的子表结构。
二、关联表无数据的核心问题
你使用了普通的InsertAsync方法,该方法仅会插入主表数据,不会处理关联的子项和关系映射。同时你的模型定义缺失了OneToMany关系的关键外键,导致ORM无法识别关联逻辑。
完整修复步骤
1. 修正模型定义(移除冗余中间表,补全外键)
删除MyItemStorageMyItems类,修改MyItem类添加指向主表的外键:
[Table("MyItemStorageTable")] public class MyItemStorage { [PrimaryKey, AutoIncrement] public int Id { get; set; } [Unique] public string Name { get; set; } public string Brand { get; set; } [OneToMany(CascadeOperations = CascadeOperation.All)] // 可选级联操作,自动同步增删改 public List<MyItem> MyItemList { get; set; } = new List<MyItem>(); // 初始化避免空引用 }
[Table("MyItemTable")] public class MyItem { [PrimaryKey, AutoIncrement] public int Id { get; set; } [Unique] public string Name { get; set; } [ForeignKey(typeof(MyItemStorage))] // 添加指向主表的外键 public int MyItemStorageId { get; set; } }
2. 调整表创建顺序
在Init方法中,先创建子表再创建主表:
static async Task Init() { if (Database is not null) { return; } Database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags); // 先创建子表,再创建主表 await Database.CreateTableAsync<MyItem>(); await Database.CreateTableAsync<MyItemStorage>(); }
3. 使用扩展方法插入关联实体
替换普通的InsertAsync为SQLite.Net.Extensions的InsertWithChildrenAsync,该方法会自动插入子项并维护关联关系:
public static async Task AddMyItemStorage(MyItemStorage myItemStorage) { await Init(); // 使用扩展方法插入主表及关联子项 await Database.InsertWithChildrenAsync(myItemStorage, recursive: true); }
额外说明
- 若需要级联删除/更新,可在
[OneToMany]特性中设置CascadeOperations = CascadeOperation.All,删除主表实体时关联子表数据会自动同步删除。 - 确保
MyItemList初始化时赋值为new List<MyItem>(),避免空引用导致关联操作失败。
内容的提问来源于stack exchange,提问作者OXO
相关产品推荐
相关产品推荐

