我遵循了有关 Entity Framework 7 的 ASP.NET 5 入门指南,并将 Microsoft SQL Server 替换为 SQLite,代码中的唯一区别在于 Startup.cs:
services.AddEntityFramework()
.AddSqlite()
.AddDbContext<BloggingContext>(options => options.UseSqlite("Filename=db.db"));
当我运行网站并导航到 /Blogs 时,出现错误:
Microsoft.Data.Sqlite.SqliteException 未被用户代码处理 错误代码=-2147467259 HResult=-2147467259 消息=SQLite 错误1: “没有这样的表:博客”来源=Microsoft.Data.Sqlite SqliteErrorCode=1 堆栈跟踪: 在 Microsoft.Data.Sqlite.Interop.MarshalEx.ThrowExceptionForRC(Int32 rc, Sqlite3Handle 数据库) 在 Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior 行为) 在 Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReader(CommandBehavior 行为) 在 System.Data.Common.DbCommand.ExecuteReader() 在 Microsoft.Data.Entity.Query.Internal.QueryingEnumerable.Enumerator.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 System.Linq.Enumerable.d__1`2.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 在 Microsoft.Data.Entity.Query.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext() 在 System.Collections.Generic.List`1..ctor(IEnumerable`1 集合) 在 System.Linq.Enumerable.ToList[TSource](IEnumerable`1 源) 在 d: rthur\documents isual studio 中的 EFGetStarted.AspNet5.Controllers.BlogsController.Index() 2015\Projects\EFGetStarted.AspNet5\src\EFGetStarted.AspNet5\Controllers\BlogsController.cs:regel 18 内部异常:
我的理解是好像没有名为“博客”的表,但是当我在 SQLite 的数据库浏览器中打开 .db 文件时,实际上有一个名为“博客”的表:
SQLite 是否需要对代码进行其他更改,或者这是实体框架的 SQLite 连接器中的错误?
很可能 EF 实际打开的数据库不是您在 DB Browser 中打开的文件。 SQLite 使用进程当前工作目录,如果在 IIS 或其他服务器中启动,则该目录可以是与源代码目录不同的文件夹。 (请参阅问题 https://github.com/aspnet/Microsoft.Data.Sqlite/issues/132 和 https://github.com/aspnet/Microsoft.Data.Sqlite/issues/55)。
为了确保您的数据库文件位于正确的位置,请使用绝对路径。示例:
public class Startup
{
private IApplicationEnvironment _appEnv;
public Startup(IApplicationEnvironment appEnv)
{
_appEnv = appEnv;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFramework()
.AddSqlite()
.AddDbContext<MyContext>(
options => { options.UseSqlite($"Data Source={_appEnv.ApplicationBasePath}/data.db"); });
}
}
取自 EF Core 文档...
从 Visual Studio 运行
要从 Visual Studio 运行此示例,您必须设置工作 手动将目录设置为项目的根目录。如果你不设置 工作目录下,出现以下 Microsoft.Data.Sqlite.SqliteException 抛出:SQLite 错误 1:“没有这样的表:博客”。
设置工作目录:
我在
netcoreapp2.0
上遇到了这个问题。有一个相关的问题可能有问题,但我不想通过夜间构建来解决它。
我的解决方案是创建并传递
SqliteConnection
而不是使用构建器字符串。
对于这个设置:
string id = string.Format("{0}.db", Guid.NewGuid().ToString());
var builder = new SqliteConnectionStringBuilder()
{
DataSource = id,
Mode = SqliteOpenMode.Memory,
Cache = SqliteCacheMode.Shared
};
像这样为 DI 编写:
var connection = new SqliteConnection(builder.ConnectionString);
connection.Open();
connection.EnableExtensions(true);
services.AddDbContext<SomeDbContext>(options => options.UseSqlite(connection));
我遇到的错误是使用这种风格的 init:
services.AddDbContext<SomeDbContext>(options => options.UseSqlite(builder.ConnectionString));
我的脚手架还有一个一次性调用:
var dbContext = serviceScope.ServiceProvider.GetService<SomeDbContext>();
dbContext.Database.OpenConnection();
dbContext.Database.EnsureCreated();
使用这种方法,我所有 DI 实例化的
SomeDbContext
副本都将指向有效的 SQLite 数据库,并且该数据库将具有根据我的实体自动创建的架构。
看起来事情已经发生了变化,因为 IApplicationEnvironment 已被 IHostingEnvironment 取代。
删除 IApplicationEnvironment \ IRuntimeEnvironment
public class Startup
{
private IHostingEnvironment _appHost;
public Startup(IHostingEnvironment appHost)
{
_appHost = appHost;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFrameworkSqlite()
.AddDbContext<MyContext>(
options => { options.UseSqlite($"Data Source={_appHost.ContentRootPath}/data.db"); });
}
}
如果您有多个 DataContext,则
EnsureCreated
方法仅在第一次调用时有效。请参阅其文档:
如果数据库存在并且有任何表,则不采取任何操作
要创建其他 DataContext 的表,请使用
RelationalDatabaseCreator databaseCreator =
(RelationalDatabaseCreator) secondDbContext.Database.GetService<IDatabaseCreator>();
databaseCreator.CreateTables();
可以设置添加配置;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source = path//DatabaseName.db");
}
该示例使用 SQLite,但您可以选择自己的数据库。
如果您有很多项目,请确保正确的项目处于活动状态。然后您将获得连接数据库的正确信息。
就我而言,这是路径问题,我正在使用清洁架构
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=../YOUR_PROJECT.Infrastructure/data.sqlite");
base.OnConfiguring(optionsBuilder);
}