为什么当我使用实体框架核心创建内存中 sqlite 数据库时表不存在?



我想创建一个内存中的SQLite数据库。

这是startup.cs

public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();            
services.AddDbContext<TestDBContext>().AddEntityFrameworkSqlite();
}

下面是数据库的模型:

public class TestModel
{
public string UserName { get; set; }        
[Key]
public string id { get; set; }
}

这是数据库的DBContext:

public class TestDBContext : DbContext
{
public virtual DbSet<TestModel> Test { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=:memory:");
}
}

这是控制器:

private readonly TestDBContext TestDBContext;
public HomeController(ILogger<HomeController> logger,TestDBContext _TestDBContext)
{
_logger = logger;
this.TestDBContext = _TestDBContext;
}
public IActionResult Index()
{
TestDBContext.Database.EnsureCreated();            
TestDBContext.SaveChanges();
TestDBContext.Test.Add(new TestModel() { User = DateTime.Now.ToString(),id=Guid.NewGuid().ToString() });
TestDBContext.SaveChanges();
return View(TestDBContext.Test.ToList());
}

每次运行时,它都会报告一个错误:

Inner Exception 1:
SqliteException: SQLite Error 1: 'no such table: Test'.

我已经使用了EnsureCreatedEnsureCreated运行没有任何错误。为什么还是这样?

EFCore 的 DbContext 始终自动打开和关闭与数据库的连接,除非传递已打开的连接。当连接关闭时,Sqlite内存数据库将被删除。所以我像这样修改了你的代码。

public void ConfigureServices(IServiceCollection services)
{
var connection = new SqliteConnection("datasource=:memory:");
connection.Open();
services.AddControllersWithViews();
services.AddDbContext<TestDBContext>(options =>
{
options.UseSqlite(connection);
});
}

和数据库上下文类 - 我添加了构造函数,以便我可以提供参数。

public class TestDBContext : DbContext
{
public TestDBContext(DbContextOptions options) : base(options)
{
}
protected TestDBContext()
{
}
public virtual DbSet<TestModel> Test { get; set; }
}

而不是在 Index 操作方法中创建数据库,而是在启动中创建它。

对于像我一样有问题并在 2023 年找到这篇文章的人:

ASP.NET 核心/.NET 7

public class ControllerTests
{
private DbContext _context;
public ControllerTests()
{
var connection = new SqliteConnection("DataSource=:memory:");
var options = new DbContextOptionsBuilder<DbContext>()
.UseSqlite(connection).Options;
_context = new DbContext(options);
_context.Database.OpenConnection();
_context.Database.EnsureCreated();
_context.Database.Migrate();
}
}
public class DbContext : DbContext
{
public DbContext(DbContextOptions<DbContext> options): base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
public DbSet<UserModel> Users { get; set; }
}

此外,选择使用DbContext.Database.Migrate()方法而不是EnsureCreated否则您将无法在以后使用迁移。

最新更新