web-dev-qa-db-fra.com

ASP.NET 5, EF 7 et SQLite - Erreur SQLite 1: «aucune table de ce type: Blog»

J'ai suivi le guide Mise en route sur ASP.NET 5 sur Entity Framework 7 et j'ai remplacé MicrosoftSqlServer par Sqlite, la seule différence dans le code réside dans Startup.cs:

services.AddEntityFramework()
    .AddSqlite()
    .AddDbContext<BloggingContext>(options => options.UseSqlite("Filename=db.db"));

Lorsque j'exécute le site Web et accède à/Blogs, j'obtiens une erreur:

Microsoft.Data.Sqlite.SqliteException n'a pas été gérée par le code utilisateur
ErrorCode = -2147467259 HResult = -2147467259 Message = SQLite Erreur 1: 'aucune table de ce type: Blog' Source = Microsoft.Data.Sqlite
SqliteErrorCode = 1 StackTrace: sur Microsoft.Data.Sqlite.Interop.MarshalEx.ThrowExceptionForRC (Int32 rc, Sqlite3Handle db) sur Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader (CommandBehavior.Sql sur Microsoft.D Comportement). SqliteCommand.ExecuteDbDataReader (comportement CommandBehavior) sur System.Data.Common.DbCommand.ExecuteReader () sur Microsoft.Data.Entity.Query.Internal.QueryingEnumerable.Enumerator.MoveNext () sur System.Linq.Enumerable.WhereSelectEnumerableMove ) sur System.Linq.Enumerable.d__1`2.MoveNext () sur System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext () sur Microsoft.Data.Entity.Query.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext () System.Collections.Generic.List`1..ctor (collection IEnumerable`1) sur System.Linq.Enumerable.ToList [TSource] (source IEnumerable`1) sur EFGetStarted.AspNet5.Controllers.BlogsController.Index () en d:\arthur\documents\visual studio 2015\Projects\EFGetStarted.AspNet5\src\EFGetStart ed.AspNet5\Controllers\BlogsController.cs: regel 18 InnerException:

Je comprends cela comme s'il n'y avait pas de table appelée "Blog", mais lorsque j'ouvre le fichier .db dans DB Browser pour SQLite, il y a en fait une table appelée "Blog":

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

SQLite nécessite-t-il d'autres modifications dans le code, ou s'agit-il d'une erreur dans le connecteur SQLite pour Entity Framework?

16
Arthur Rump

Il est très probable que la base de données actuellement ouverte par EF ne soit pas le fichier que vous ouvrez dans DB Browser. SQLite utilise le répertoire de travail actuel du processus qui, s'il est lancé dans IIS ou d'autres serveurs, peut être un dossier différent de votre répertoire de code source. (Voir les problèmes https: // github. com/aspnet/Microsoft.Data.Sqlite/issues/132 et https://github.com/aspnet/Microsoft.Data.Sqlite/issues/55 ).

Pour vous assurer que votre fichier db est au bon endroit, utilisez un chemin absolu. Exemple:

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

Tiré de la documentation EF Core ...

Exécuter à partir de Visual Studio

Pour exécuter cet exemple à partir de Visual Studio, vous devez définir manuellement le répertoire de travail comme racine du projet. Si vous ne définissez pas le répertoire de travail, l'exception Microsoft.Data.Sqlite.SqliteException suivante est levée: Erreur SQLite 1: 'no such table: Blogs'.

Pour définir le répertoire de travail:

  • Dans Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Propriétés.
  • Sélectionnez l'onglet Debug dans le volet gauche.
  • Définissez répertoire de travail dans le répertoire du projet.
  • Enregistrez les modifications.
8
jjoselon

Il semble que les choses ont changé car IApplicationEnvironment a été remplacé par IHostingEnvironment.

Suppression de 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"); });
    }
}
5
T Brown

J'ai eu ce problème le netcoreapp2.0. Il y a un issue qui peut être en cause, mais je ne voulais pas le résoudre en passant à une version nocturne.

La solution pour moi était de créer et de passer un SqliteConnection au lieu d'utiliser la chaîne du générateur.

Donc pour cette configuration:

string id = string.Format("{0}.db", Guid.NewGuid().ToString());

var builder = new SqliteConnectionStringBuilder()
{
    DataSource = id,
    Mode = SqliteOpenMode.Memory,
    Cache = SqliteCacheMode.Shared
};

Composez pour la DI comme ceci:

var connection = new SqliteConnection(builder.ConnectionString);
connection.Open();
connection.EnableExtensions(true);
services.AddDbContext<SomeDbContext>(options => options.UseSqlite(connection));

L'erreur que j'ai eue était d'utiliser ce style d'init:

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

Mon échafaudage a également un appel unique à:

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

En utilisant cette approche, toutes mes copies instanciées DI de SomeDbContext pointeraient toutes vers une base de données SQLite valide, et cette base de données aurait un schéma créé automatiquement selon mes entités.

3
user326608

Je l'ai fait et j'avais toujours du mal à charger la base de données. J'ai ajouté le code suivant dans le constructeur pour le contexte de la base de données: Database.EnsureCreated();


Maintenant, mon fichier de contexte ressemble à ceci: BoardGameDBContextFile

Il a créé une nouvelle base de données sur mon nouveau site d'hébergement Azure, donc si vous avez beaucoup de données existantes à migrer, cela ne fonctionnera pas. Cela a fonctionné pour moi alors j'ai pensé que je partagerais.

2
Michael