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

SQLite与EF6使用GUID主键时的异常查询问题

问题根源:SQLite与EF的Guid格式不匹配

这个问题的核心在于SQLite没有原生的GUID数据类型,而EF(配合SQLite CodeFirst)对Guid的默认存储格式,和你代码中使用的Guid字符串格式不一致,导致查询时无法匹配。

具体原因拆解:

  1. SQLite的Guid存储逻辑:当EF将Guid类型映射到SQLite时,默认会把Guid转换成小写、无连字符的字符串(比如 d46d98f3c262468a9c2883d81080cf18)或者二进制数据存储到数据库中。
  2. 你的代码中的Guid格式:你在Entity类里用带连字符的大写Guid字符串初始化(D46D98F3-C262-468A-9C28-83D81080CF18),查询时也是用这个格式的Guid值。
  3. 上下文缓存的干扰:
    • 第一个上下文里的Find能找到数据,是因为它先从上下文的内存缓存中读取,而不是直接查数据库;
    • 当你先调用ToArrayAsync加载所有数据到缓存后,Find同样优先查缓存所以能找到,但LINQ的Where语句会生成SQL直接查询数据库,因为格式不匹配所以查不到;
    • 新上下文没有缓存,不管用Find还是LINQ都会查数据库,自然找不到数据。

解决方法

最可靠的方式是显式配置Guid的转换规则,让EF在存储和查询时统一格式:

修改MyDbContext的OnModelCreating方法,为Entity.Id属性指定转换逻辑:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    Database.SetInitializer(new SqliteDropCreateDatabaseWhenModelChanges<MyDbContext>(modelBuilder));
    
    // 配置Guid存储为无连字符的字符串,查询时自动转换
    modelBuilder.Entity<Entity>()
        .Property(e => e.Id)
        .HasConversion(
            guid => guid.ToString("N"), // 存储时转成无连字符的字符串
            str => Guid.Parse(str)      // 查询时将字符串转回Guid
        );
}

这样无论你用什么格式初始化Guid,EF都会统一转换成无连字符的字符串存储,查询时也会自动匹配数据库中的格式,就能解决查询不到的问题。

为什么string/int类型正常?

当主键是string或int时,不存在格式转换的问题:

  • string类型会原封不动存储你传入的字符串,查询时直接匹配;
  • int类型是SQLite原生支持的数值类型,匹配逻辑简单直接,不会出现格式不兼容的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:05:58