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

在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设计的扩展库,它支持导航属性自动加载。

  1. 安装NuGet包:搜索并安装SQLiteNetExtensionsAsync(适配异步操作场景)
  2. 配置实体类导航属性:
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; }
}
  1. 使用扩展方法加载关联数据:
    添加命名空间引用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 10:05:29