在Xamarin.Forms中如何使用.Include()?解决SQLite-net-pcl报错
解决SQLite-net-pcl中AsyncTableQuery无Include方法的问题
报错原因
SQLite-net-pcl是轻量级ORM,核心库不内置EF风格的Include()导航属性加载扩展,所以AsyncTableQuery类型自然没有这个方法,也找不到对应的扩展实现。
解决方案
方案1:手动查询关联数据
如果关联逻辑简单,直接分两次查询或者用SQL Join手动映射结果即可:
方式A:先查主表再补关联数据
public async Task<List<Note>> GetNotesWithArtikelAsync() { // 先获取所有Note var notes = await database.Table<Note>().ToListAsync(); // 循环为每个Note加载对应的Artikel(假设Artikel用NoteId作为外键) foreach (var note in notes) { note.Artikel = await database.Table<Artikel>() .FirstOrDefaultAsync(a => a.NoteId == note.Id); } return notes; }
方式B:用原生SQL Join查询
适合需要一次性获取关联数据的场景,需自定义包含两个表字段的类接收结果:
// 自定义联合查询结果类,字段对应SQL查询的别名 public class NoteArtikelJoin { public int NoteId { get; set; } public string NoteContent { get; set; } public int ArtikelId { get; set; } public string ArtikelName { get; set; } } public async Task<List<Note>> GetNotesWithArtikelViaSqlAsync() { var sql = @"SELECT n.Id AS NoteId, n.Content AS NoteContent, a.Id AS ArtikelId, a.Name AS ArtikelName FROM Note n LEFT JOIN Artikel a ON n.Id = a.NoteId"; var joinResults = await database.QueryAsync<NoteArtikelJoin>(sql); // 映射回Note带Artikel的对象列表 return joinResults.Select(r => new Note { Id = r.NoteId, Content = r.NoteContent, Artikel = new Artikel { Id = r.ArtikelId, Name = r.ArtikelName } }).ToList(); }
方案2:使用SQLite-net-extensions扩展库
如果项目有大量关联查询需求,推荐使用专门为SQLite-net设计的扩展库,它支持导航属性自动加载。
- 安装NuGet包:搜索并安装
SQLiteNetExtensionsAsync(适配异步操作场景) - 配置实体类导航属性:
using SQLiteNetExtensions.Attributes; public class Note { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Content { get; set; } // 配置一对一关联,CascadeOperations可选,用于级联增删改 [OneToOne(CascadeOperations = CascadeOperation.All)] public Artikel Artikel { get; set; } } public class Artikel { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Name { get; set; } // 配置外键关联Note表 [ForeignKey(typeof(Note))] public int NoteId { get; set; } }
- 使用扩展方法加载关联数据:
添加命名空间引用using SQLiteNetExtensionsAsync.Extensions;,然后修改你的方法:
public async Task<List<Note>> GetNotesInclude() { // 加载所有Note及其关联的Artikel return await database.GetAllWithChildrenAsync<Note>(includeChildren: true); // 如果需要过滤Note,可结合Table和WithChildrenAsync: // return await database.Table<Note>() // .Where(n => n.Content.Contains("关键词")) // .WithChildrenAsync(); }
总结
- 简单关联场景:手动查询足够灵活,无需额外依赖
- 复杂关联场景:SQLite-net-extensions能大幅简化代码,支持一对一、一对多、多对多等多种关联类型
内容的提问来源于stack exchange,提问作者Malik Alhanouti
相关产品推荐
相关产品推荐

