我目前正在尝试使用 C# 为一个严重依赖 Entity Framework Core 的项目编写单元测试。为了做到这一点,我决定使用 SQLite 内存数据库,并从here的示例中汲取灵感,我编写了以下类:
public class SqliteEFCoreContextInitializer<T> : IDisposable where T : DbContext
{
private SQLiteConnection connection;
private DbContextOptions<T> contextOptions;
private Func<DbContextOptions<T>, T> contextInstantationFunction;
// The parameter _contextInstantationFunction is there solely to get around the impossibility to directly call the context constructor from the generic type T
public SqliteEFCoreContextInitializer(Func<DbContextOptions<T>,T> _contextInstantationFunction)
{
contextInstantationFunction = _contextInstantationFunction;
connection = new SQLiteConnection("Data Source=:memory:");
connection.Open();
contextOptions = new DbContextOptionsBuilder<T>().UseSqlite(connection).Options;
using T context = CreateContext();
context.Database.EnsureCreated();
}
public void Dispose()
{
connection.Dispose();
}
public T CreateContext()
{
return contextInstantationFunction(contextOptions);
}
}
这个类应该被实例化,然后像这样使用:
// Instantiation
SqliteEFCoreContextInitializer<MyContext> sqliteContextInitializer = new(options => new MyContext(options));
//Getting the SQLite in-memory DbContext
MyContext context = sqliteContextInitializer.CreateContext();
我遇到的问题是,无论我的数据库模式如何,我似乎总是遇到错误
SQL 逻辑错误:仅在 INTEGER PRIMARY KEY 上允许 AUTOINCRMENT
执行
context.Database.EnsureCreated();
时。经过一些实验,我发现即使我的模式仅包含一个表,除了整数主键之外没有任何列,也会引发此错误!我到底做错了什么?
另外,我不知道这是否相关,但在这个项目中,我被迫使用现已过时的 EF Core 5.0。
经过更多实验,我发现错误是由于我的主键数据类型设置为
NUMBER(10)
而 Sqlite 要求它们为 INTEGER
引起的。更改数据类型解决了问题。我必须承认,一开始我并没有想到这两种数据类型将以足够不同的方式处理以产生此错误(毕竟它们都意味着表示整数),但我现在意识到我非常天真.