Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to determine the provider name for provider factory of type "System.Data.Sqlite.SqliteFactory"

I want to use sqlite entity framework in my web api project, but it always can't work well,

here is my development enviroment.

1.Visual studio 2013, .net framework 4.5

  1. sqlite package version is 1.0.97, I installed below packages

    system.data.sqlite, system.data.sqlite.ef6, system.data.sqlite.linq

  2. EntityFramework is 6.1.3

Here is exception that I got

Unable to determine the provider name for provider factory of type 'System.Data.SQLite.SQLiteFactory'. Make sure that the ADO.NET provider is installed or registered in the application config

Here is my webconfig

<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
  </configSections>

  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />  <!--type="System.Data.SQLite.EF6.SQLiteProviderServices-->
    </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" />
    </DbProviderFactories>
  </system.data>
  <connectionStrings>
    <add name="Sqlite" connectionString="data source=&quot;D:\MyWebAPI\src\MyWeb.Api\App_Data\sqlite_test.db&quot;" providerName="System.Data.SQLite.EF6" />
  </connectionStrings>
</configuration>

I can connect sqlite database file through "connect to database" in tool of visual studio, I also can generate entity using code first.

but I can't get data normal

Here is my code

 public partial class Sqlite : DbContext
    {
        public Sqlite()
            : base("name=Sqlite")
        {
        }

        public virtual DbSet<AuthorizationLog> AuthorizationLogs { get; set; }
        public virtual DbSet<Checksum> Checksums { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<AuthorizationLog>()
                .Property(e => e.ClientKey)
                .IsUnicode(false);

            modelBuilder.Entity<AuthorizationLog>()
                .Property(e => e.Login)
                .IsUnicode(false);

            modelBuilder.Entity<AuthorizationLog>()
                .Property(e => e.Password)
                .IsUnicode(false);

            modelBuilder.Entity<AuthorizationLog>()
                .Property(e => e.ConnectionString)
                .IsUnicode(false);
        }
    }

   public class ValuesController : ApiController
    {
        // GET api/values
        Sqlite ctx = new WebApi2Demo.Sqlite();
        public IEnumerable<Checksum> Get()
        {
            return ctx.Checksums;
        }
	}
like image 762
zhnglicho Avatar asked Aug 03 '15 06:08

zhnglicho


2 Answers

I got the answer by myself, but I still don't know the root cause, now it works. I changed webconfig, here is the webconfig that make my project to work.

I added a provider that is "System.Data.Sqlite", Please note its type that is same with System.Data.Sqlite.EF6

  <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />

  <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
  <remove invariant="System.Data.SQLite.EF6" />

Here is all configure.

 <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" />
      <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
    </providers>
  </entityFramework>

  <system.data>
    <DbProviderFactories>
      <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" />
      <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" />
    </DbProviderFactories>
  </system.data>
like image 82
zhnglicho Avatar answered Oct 21 '22 08:10

zhnglicho


That was a super-great answer zhnglicho!

Another option, aside from placing the providers and DbProviderFactories into the app.config or web.config, is to code your ProviderFactories and use it in your implementation of DbContext.

Usings:

using System.Data.Entity;
using System.Data.Entity.Core.Common;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.SQLite;
using System.Data.SQLite.EF6;

Config Class:

public class SQLiteConfiguration : DbConfiguration
{
    public SQLiteConfiguration()
    {
        SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance);
        SetProviderFactory("System.Data.SQLite.EF6", SQLiteProviderFactory.Instance);
        SetProviderServices("System.Data.SQLite", (DbProviderServices)SQLiteProviderFactory.Instance.GetService(typeof(DbProviderServices)));
    }
}

Place this in your constructor:

public PythonContext() : base($"name=pythonSource")
{
    DbConfiguration.SetConfiguration(new SQLiteConfiguration());
}

I've run unit tests against both methods (this one and the zhnglicho answer) and i've not found any speed differences.

Debug Output (getting a record count and a random quote from the sqlitedb):

Found 18307 Records
Presenter: 'And Miles Yellowbird, up high in banana tree, the golfer and 
inventor of Catholicism.'


Debug Trace:
Native library pre-loader is trying to load native SQLite library "C:\Users\***\***\\SQLiteTests\bin\Debug\x64\SQLite.Interop.dll"...

I up-voted the previous answer as it worked for me, but this is just a suggestion if you don't want to jack with your configs. ~ PEACE!

sqlite entityframework

like image 18
PixelSyndicate Avatar answered Oct 21 '22 10:10

PixelSyndicate