sqlite-net-pcl库是否支持一对多、多对多关系?Xamarin.Forms新手求助
嘿,刚上手Xamarin.Forms和sqlite-net-pcl的话,你的问题确实是新手常问的——我来给你掰扯清楚:
sqlite-net-pcl的关系支持情况
首先明确两个核心点:
- 一对多关系:sqlite-net-pcl原生支持,只需要手动定义外键和导航属性就能实现
- 多对多关系:它没有内置的自动映射支持,需要你手动创建中间关联表来处理
一对多关系的实现步骤(以分类&产品为例)
下面用「分类(Category)→ 多个产品(Product)」的典型场景,一步步演示具体操作:
1. 定义实体类
先创建两个实体,明确外键关联和内存中的导航属性:
public class Category { // 主键,自动递增 [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Name { get; set; } // 导航属性:存储该分类下的所有产品 // 加[Ignore]是因为这个属性不需要存入数据库,仅用于内存中关联数据 [Ignore] public List<Product> Products { get; set; } = new List<Product>(); } public class Product { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Name { get; set; } // 外键:关联到Category的Id字段 [ForeignKey(typeof(Category))] public int CategoryId { get; set; } // 导航属性:存储该产品所属的分类 [Ignore] public Category Category { get; set; } }
2. 初始化数据库连接
创建本地数据库文件并生成对应的数据表:
// 获取适配各平台的本地存储路径 var dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Shop.db3"); // 初始化异步连接(推荐用Async版本,避免阻塞UI线程) var db = new SQLiteAsyncConnection(dbPath); // 创建Category和Product两张表 await db.CreateTablesAsync<Category, Product>(); // 可选:开启SQLite外键约束,支持级联删除/更新等操作 await db.ExecuteAsync("PRAGMA foreign_keys = ON;");
3. 插入关联数据
先插入父实体(分类),再插入子实体(产品)并绑定外键:
// 先插入一个分类 var electronicsCategory = new Category { Name = "电子产品" }; await db.InsertAsync(electronicsCategory); // 插入属于该分类的两个产品,指定CategoryId为刚插入的分类ID var phone = new Product { Name = "智能手机", CategoryId = electronicsCategory.Id }; var laptop = new Product { Name = "笔记本电脑", CategoryId = electronicsCategory.Id }; await db.InsertAllAsync(new List<Product> { phone, laptop });
4. 查询关联数据
sqlite-net-pcl原生不会自动加载关联数据,需要手动查询并绑定到导航属性:
// 第一步:查询目标分类 var targetCategory = await db.Table<Category>() .FirstOrDefaultAsync(c => c.Name == "电子产品"); // 第二步:查询该分类下的所有产品,赋值给导航属性 if (targetCategory != null) { targetCategory.Products = await db.Table<Product>() .Where(p => p.CategoryId == targetCategory.Id) .ToListAsync(); } // 现在targetCategory.Products里就包含所有关联的产品了
如果觉得手动查询太繁琐,可以安装sqlite-net-extensions扩展包,它提供了GetWithChildrenAsync这类方法能自动加载关联数据——不过这属于额外扩展,原生sqlite-net-pcl还是需要手动处理。
5. 处理更新/删除
如果开启了外键约束,你可以在创表时指定级联操作,比如删除分类时自动删除所有关联产品:
// 用自定义SQL语句创表(代替CreateTablesAsync),添加级联删除约束 await db.ExecuteAsync(@"CREATE TABLE IF NOT EXISTS Product ( Id INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT, CategoryId INTEGER, FOREIGN KEY (CategoryId) REFERENCES Category(Id) ON DELETE CASCADE )"); // 之后删除分类时,所有关联的产品会被自动删除 await db.DeleteAsync(electronicsCategory);
关于多对多关系的补充
比如「学生(Student)→ 多门课程(Course)」的多对多场景,你需要创建一个中间表StudentCourse来存储关联关系:
public class StudentCourse { [PrimaryKey, AutoIncrement] public int Id { get; set; } [ForeignKey(typeof(Student))] public int StudentId { get; set; } [ForeignKey(typeof(Course))] public int CourseId { get; set; } }
查询时,先通过中间表找到关联的ID,再查询对应的实体,逻辑和一对多类似,只是多了一步中间表的查询操作。
内容的提问来源于stack exchange,提问作者Md Tayeb Himel
相关产品推荐
相关产品推荐

