“没有这样的表:博客”-表“博客”确实存在时出错

问题描述 投票:0回答:10

我遵循了有关 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 文件时,实际上有一个名为“博客”的表:

Screenshot from DB Browser for SQLite showing a table called 'Blog'

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

asp.net entity-framework sqlite asp.net-core entity-framework-core
10个回答
37
投票

很可能 EF 实际打开的数据库不是您在 DB Browser 中打开的文件。 SQLite 使用进程当前工作目录,如果在 IIS 或其他服务器中启动,则该目录可以是与源代码目录不同的文件夹。 (请参阅问题 https://github.com/aspnet/Microsoft.Data.Sqlite/issues/132https://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"); });
    }
}

33
投票

我这样做了,但加载数据库时仍然遇到问题。 我在数据库上下文的构造函数中添加了以下代码:

Database.EnsureCreated();


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

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


16
投票

取自 EF Core 文档...

从 Visual Studio 运行

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

设置工作目录:

  • 解决方案资源管理器中,右键单击项目,然后选择属性
  • 选择左侧窗格中的调试选项卡。
  • 工作目录设置为项目目录。
  • 保存更改。

13
投票

我在

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 数据库,并且该数据库将具有根据我的实体自动创建的架构。


6
投票

看起来事情已经发生了变化,因为 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"); });
    }
}

2
投票

如果您有多个 DataContext,则

EnsureCreated
方法仅在第一次调用时有效。请参阅其文档:

如果数据库存在并且有任何表,则不采取任何操作

要创建其他 DataContext 的表,请使用

 RelationalDatabaseCreator databaseCreator = 
(RelationalDatabaseCreator) secondDbContext.Database.GetService<IDatabaseCreator>();
databaseCreator.CreateTables();

1
投票

可以设置添加配置;

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source = path//DatabaseName.db");
    }

该示例使用 SQLite,但您可以选择自己的数据库。


0
投票

如果您有很多项目,请确保正确的项目处于活动状态。然后您将获得连接数据库的正确信息。


0
投票

就我而言,这是路径问题,我正在使用清洁架构

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlite("Data Source=../YOUR_PROJECT.Infrastructure/data.sqlite");

    base.OnConfiguring(optionsBuilder);
}

-1
投票

我遇到了同样的问题,我在此链接中找到了答案:

https://www.youtube.com/watch?v=yRmMYrSROPs 只需通过命令更新您的数据库:

dotnet ef 数据库更新

© www.soinside.com 2019 - 2024. All rights reserved.