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

使用EF Core创建内存SQLite数据库时提示表不存在的问题

解决SQLite内存数据库“no such table”问题

这个问题的核心是SQLite内存数据库的特殊行为:每个内存数据库完全绑定到单个数据库连接——当连接关闭时,内存里的数据库就被销毁了;而每次新建连接,都会得到一个全新的空内存数据库。

你的代码里,EnsureCreated()和后续的Add()、ToList()操作实际上使用的是不同的数据库连接,所以前一个连接创建的表在新连接里根本不存在,才会抛出这个错误。下面是具体的解决步骤和修改后的代码:

解决方案:共享同一个数据库连接

要让所有操作都在同一个连接上执行,我们可以通过依赖注入控制连接的生命周期,保持连接打开并复用它。

1. 修改Startup.cs的服务配置

我们先注册一个单例的SQLite连接(确保整个应用生命周期内只用这一个连接),再让DbContext使用这个已打开的连接:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

    // 注册单例的SQLite内存连接,保持打开状态
    services.AddSingleton<SqliteConnection>(sp =>
    {
        var connection = new SqliteConnection("Data Source=:memory:");
        connection.Open();
        return connection;
    });

    // 配置DbContext使用上面的共享连接
    services.AddDbContext<TestDBContext>((serviceProvider, options) =>
    {
        var sqliteConnection = serviceProvider.GetRequiredService<SqliteConnection>();
        options.UseSqlite(sqliteConnection);
    });
}

2. 更新TestDBContext类

移除硬编码的OnConfiguring方法,改为通过构造函数接收配置(符合依赖注入的最佳实践):

public class TestDBContext : DbContext
{
    public virtual DbSet<TestModel> Test { get; set; }

    // 依赖注入DbContextOptions
    public TestDBContext(DbContextOptions<TestDBContext> options) : base(options)
    {
    }
}

3. 调整控制器代码

确保所有数据库操作都复用同一个DbContext实例(也就是同一个共享连接):

private readonly TestDBContext _testDBContext;
private readonly ILogger<HomeController> _logger;

public HomeController(ILogger<HomeController> logger, TestDBContext testDBContext)
{
    _logger = logger;
    _testDBContext = testDBContext;
}

public IActionResult Index()
{
    // 在共享连接上创建表
    _testDBContext.Database.EnsureCreated();

    // 添加新数据并保存
    var newTestEntry = new TestModel
    {
        UserName = DateTime.Now.ToString(),
        id = Guid.NewGuid().ToString()
    };
    _testDBContext.Test.Add(newTestEntry);
    _testDBContext.SaveChanges();

    // 查询数据(仍然使用同一个连接)
    var testDataList = _testDBContext.Test.ToList();
    return View(testDataList);
}

为什么原代码会失败?

原代码中,每次创建TestDBContext实例时,OnConfiguring方法都会新建一个SQLite连接。EnsureCreated()在第一个连接上创建了表,但这个连接在操作完成后会被自动释放,内存数据库也随之消失。当你执行Add()和ToList()时,又创建了新的连接,对应的是一个全新的空内存数据库,自然找不到之前创建的表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 12:42:38