【问题标题】:ASP.NET 5, EF 7 and SQLite - SQLite Error 1: 'no such table: Blog'ASP.NET 5、EF 7 和 SQLite - SQLite 错误 1:“没有这样的表:博客”
【发布时间】:2016-02-01 00:05:17
【问题描述】:

我遵循了关于 Entity Framework 7 的 Getting Started on ASP.NET 5 指南,并将 MicrosoftSqlServer 替换为 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:\arthur\documents\visual studio 中的 EFGetStarted.AspNet5.Controllers.BlogsController.Index() 2015\Projects\EFGetStarted.AspNet5\src\EFGetStarted.AspNet5\Controllers\BlogsController.cs:regel 18 内部异常:

我理解这好像没有名为“Blog”的表,但是当我在 DB Browser for SQLite 中打开 .db 文件时,实际上有一个名为“Blog”的表:

SQLite 是否需要对代码进行其他更改,或者这是实体框架的 SQLite 连接器中的错误?

【问题讨论】:

  • 你的BlogsController.Index 方法是什么样的?
  • 你连接到正确的数据库了吗?
  • @DavidG public IActionResult Index() { return View(_context.Blogs.ToList()); }
  • @DevilSuichiro 这不是 EF 处理的吗?整个程序中只有一个地方提供了有关数据库位置的信息。 EF 使用该信息来创建数据库,它也应该用于连接它,不是吗?
  • 很可能是的。你用 db 浏览器连接到同一个吗?

标签: asp.net entity-framework sqlite asp.net-core entity-framework-core


【解决方案1】:

我这样做了,但仍然无法加载数据库。我在数据库上下文的构造函数中添加了以下代码: Database.EnsureCreated();


现在我的上下文文件如下所示:

它在我的新 Azure 托管站点上创建了一个新数据库,因此如果您有大量现有数据要迁移,这将不起作用。它对我有用,所以我想分享一下。

【讨论】:

  • 哇,这也正是我的问题。我不明白为什么 EF Core 文档说我的种子数据将被填充,种子数据函数正在运行,然后之后的任何查询总是会抛出一个表不存在异常!谢谢!!
  • 我关注docs.microsoft.com/en-us/ef/core/get-started/overview/… 和这个解决方案“Database.EnsureCreated();”由@Michael 提供以消除此错误。希望它可以帮助某人。
【解决方案2】:

取自 EF Core 文档...

从 Visual Studio 运行

要从 Visual Studio 运行此示例,您必须设置工作 手动将目录作为项目的根目录。如果你不设置 工作目录,如下 Microsoft.Data.Sqlite.SqliteException 抛出:SQLite 错误 1:'没有这样的表:博客'。

设置工作目录:

  • Solution Explorer 中,右键单击项目,然后选择 Properties
  • 选择左侧窗格中的调试选项卡。
  • 工作目录设置为项目目录。
  • 保存更改。

【讨论】:

  • 通过阅读您的回答@jjoselon,我能够找出我自己的问题,所以如果其他人和我一样,我会写这篇评论。我在 Mac 上使用 asp.net core 3.1,实体框架核心。我在主项目下有 3 个子项目,每次我尝试将一些数据插入表中时都会出现 SQLite 错误(即使表存在)。为了解决这个问题,右键单击我正在运行的子项目,使用 -> 自定义配置运行并在目录中运行的字段中选择相应项目的目录。希望对某人有所帮助。
  • @jjoselon 您的建议解决了我花了两天时间解决的问题(谢谢)。我使用EF Core.NET 4.8 的启动项目,.NET Standard Library 2.0SQLite 的项目。而且,启动项目没有找到SQLite db。您能否提供您在上述解决方案中引用的 EF Core 文档的链接?
【解决方案3】:

我在netcoreapp2.0 遇到了这个问题。有一个相关的issue 可能有问题,但我不想通过夜间构建来解决它。

我的解决方案是创建并传递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));

我遇到的错误是使用这种初始化风格:

services.AddDbContext<SomeDbContext>(options => options.UseSqlite(builder.ConnectionString));

我的脚手架也有一次性调用:

var dbContext = serviceScope.ServiceProvider.GetService<SomeDbContext>();
dbContext.Database.OpenConnection();
dbContext.Database.EnsureCreated();

使用这种方法,SomeDbContext 的所有 DI 实例化副本都将指向一个有效的 SQLite 数据库,并且该数据库将根据我的实体自动创建架构。

【讨论】:

  • 最后一个 sn-p 是我这个问题的实际关键。 SQLite 连接的行为与我使用的其他连接不同。
【解决方案4】:

看起来事情发生了变化,因为 IApplicationEnvironment 已被 IHostingEnvironment 替换。

Removing 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"); });
    }
}

【讨论】:

  • 如果要部署本地数据库,还要检查数据库文件是否在构建时复制到输出目录(右键单击“data.db”-> 属性/复制到输出目录/始终复制)发布时到服务器。
【解决方案5】:

EF 实际打开的数据库很可能不是您在 DB Browser 中打开的文件。 SQLite 使用进程当前工作目录,如果在 IIS 或其他服务器中启动,它可以是与源代码目录不同的文件夹。 (参见问题https://github.com/aspnet/Microsoft.Data.Sqlite/issues/132https://github.com/aspnet/Microsoft.Data.Sqlite/issues/55)。

为确保您的 db 文件位于正确的位置,请使用绝对路径。示例:

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"); });
    }
}

【讨论】:

  • 非常感谢您分享这个答案。我使用 ASP.NET Core 1.0 遇到了这个问题。我在 appsettings.json 中指定了我的数据源,它似乎不喜欢这个变量,所以我提供了一个像这样的硬编码路径:“ConnectionStrings”:{“DefaultConnection”:“Data Source=C:\\aspnetcoresqllitedbs\ \data\\WebApplication.db" }
  • 还要确保——特别是如果你像我这样在跨平台环境中工作——你使用 unix 或 windows 文件路径约定。虽然在 Windows 上,您的程序可能会同时读取以下路径: "\\" 例如 "/" ,但在 Linux 上 "\\" 可能无法读取您的文件。来自 EF Core 的错误消息只是误导 :)
猜你喜欢
  • 2010-12-29
  • 2016-11-18
  • 2015-05-11
  • 1970-01-01
  • 1970-01-01
  • 2017-02-09
  • 2015-09-07
  • 1970-01-01
  • 2018-03-27
相关资源
最近更新 更多