35

I am trying to get a simple code first example to work in a console app using SQLite and EF6, however I am running into multiple errors: I created a new console project in VS 2015. Then install EF (6.1.3) and System.Data.SQLite (1.0.102) via NuGet.

Try to run a simple program:

namespace SQLiteConsole1
{
    class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    class MyContext : DbContext
    {
        public DbSet<Person> Persons { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var db = new MyContext())
            {
                var person = new Person() { Name = "John" };
                db.Persons.Add(person);
                db.SaveChanges();
            }
        }
    }
}

This is what my App.Config looks like this:

  <connectionStrings>
    <add name="MyContext" connectionString="Data Source=C:\Temp\Test.sqlite" providerName="System.Data.SQLite" />
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
    </providers>
  </entityFramework>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite.EF6" />
      <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
    <remove invariant="System.Data.SQLite" /><add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /></DbProviderFactories>
  </system.data>

When I first run this program I get the following error:

Unhandled Exception: System.InvalidOperationException: No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SQLite'. Make sure the provider is registered in the 'entityFramework' section of the application config file."

So I change <provider invariantName="System.Data.SQLite.EF6" to <provider invariantName="System.Data.SQLite", then I get this error:

Unhandled Exception: System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. System.Data.Entity.Core.UpdateException: An error occurred while updating the entries. See the inner exception for details. System.Data.SQLite.SQLiteException: SQL logic error or missing database no such table: People

What needs to be changed to get this simple example working?

Kevin
  • 16,549
  • 8
  • 60
  • 74
RaelB
  • 3,301
  • 5
  • 35
  • 55
  • Answered by: https://stackoverflow.com/questions/22174212/entity-framework-6-with-sqlite-3-code-first-wont-create-tables and: https://stackoverflow.com/questions/62509583/sqlite-entity-framework-code-first-which-nuget-package – Bernard Hauzeur Sep 09 '22 at 09:20

2 Answers2

38

A similar question is asked over here: Entity Framework 6 with SQLite 3 Code First - Won't create tables

kjbartel gives very useful explanation that table creation is not supported by the EF SQLite Driver.

Also see https://github.com/msallin/SQLiteCodeFirst, which provides an excellent solution. I installed the SQLite.CodeFirst NuGet package, and added the below code, then the app works fine:

    class MyContext : DbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            var sqliteConnectionInitializer = new SqliteCreateDatabaseIfNotExists<MyContext>(modelBuilder);
            Database.SetInitializer(sqliteConnectionInitializer);
        }
        public DbSet<Person> Persons { get; set; }
    }
Community
  • 1
  • 1
RaelB
  • 3,301
  • 5
  • 35
  • 55
  • Is there anything special to note here? I've got a connection string defined as and have the following in my OnModelCreating, but I'm getting an error "The underlying provider failed on Open": var sqliteConnectionInitializer = new SqliteCreateDatabaseIfNotExists(modelBuilder); Database.SetInitializer(sqliteConnectionInitializer); – Derek Greer Oct 12 '16 at 21:31
  • This is what my connection string looked like: ``. Does that make a difference? – RaelB Oct 12 '16 at 23:09
  • No, using a relative vs. absolute path doesn't seem to be the issue. – Derek Greer Oct 13 '16 at 13:33
  • I got it. My issue ended up being that I was creating the context only with the connection string, but without the provider. I just needed to use the name of the connection string instead of the actual connection string. – Derek Greer Oct 13 '16 at 16:06
  • Does this support also lazyloading and eagerly loading? – Emil Dec 18 '16 at 03:23
  • I am pretty sure this answer is out-of-date. As of Oct 2017, the SQLite EF6 provider seems to be able to create tables. – Moby Disk Oct 18 '17 at 01:45
  • @MobyDisk Can you share an example of SQLite EF6 provider being used to create tables? I stumbled across this issue today ad it still doesn't seem to work. Thanks – andreapier Nov 24 '17 at 15:49
0

You need to initialize your database with the tables for your models. Notice the error "SQL logic error or missing database no such table: People".

That means you need to run SQL to create the corresponding tables in the database, thankfully, if using VS, under the context menu while in the model editor (*.edmx files), there is an option to have it auto-generate the SQL and execute it to create the table entries in the database for you based on the model. Note: sometimes the auto-generated for non MS-SQL can have issues that need to be manually fixed before it will compile/run.

Ben Abraham
  • 482
  • 5
  • 10
  • 1
    My understanding is that EF Code First should generate all tables automatically. That is one of the main purposes of an ORM... – RaelB Jul 24 '16 at 22:57
  • AFAIK, the only thing that is fully auto-generated is the client-side C# model classes, and those definitions can be quickly updated from a newer database model (eg. column added to a table), but going the other way (Model -> DB Layout) only generates a complete DDL DROP/CREATE file. – Ben Abraham Jul 24 '16 at 23:06
  • 2
    Are you specifically talking about SQLite or any Code First? – RaelB Jul 25 '16 at 01:00