web-dev-qa-db-fra.com

Impossible de déterminer le nom du fournisseur pour la fabrique de fournisseurs de type "System.Data.Sqlite.SqliteFactory"

Je souhaite utiliser le framework d'entité sqlite dans mon projet d'API Web, mais cela ne fonctionne pas toujours bien,

voici mon environnement de développement.

1.Visual studio 2013, .net framework 4.5

  1. la version du package sqlite est 1.0.97, j'ai installé ci-dessous les packages

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

  2. EntityFramework est 6.1.3

Voici l'exception que j'ai eue

Impossible de déterminer le nom du fournisseur pour la fabrique de fournisseurs de type 'System.Data.SQLite.SQLiteFactory'. Assurez-vous que le fournisseur ADO.NET est installé ou enregistré dans la configuration de l'application

Voici ma configuration Web

<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>

Je peux connecter le fichier de base de données sqlite via "se connecter à la base de données" dans l'outil de Visual Studio, je peux également générer une entité en utilisant d'abord du code.

mais je ne peux pas obtenir des données normales

Voici mon 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;
        }
        }
20
zhnglicho

J'ai obtenu la réponse par moi-même, mais je ne connais toujours pas la cause profonde, maintenant cela fonctionne. J'ai changé webconfig, voici la webconfig qui fait fonctionner mon projet.

J'ai ajouté un fournisseur qui est "System.Data.Sqlite", veuillez noter son type qui est le même avec 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" />

Voici tout configurer.

 <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>
50
zhnglicho

Ce fut une super-grande réponse zhnglicho!

Une autre option, en plus de placer les fournisseurs et DbProviderFactories dans app.config ou web.config, consiste à coder vos ProviderFactories et à les utiliser dans votre implémentation de DbContext.

Utilisations:

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;

Classe de configuration:

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

Placez ceci dans votre constructeur:

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

J'ai exécuté des tests unitaires contre les deux méthodes (celle-ci et la réponse zhnglicho) et je n'ai trouvé aucune différence de vitesse.

Sortie de débogage (obtention d'un nombre d'enregistrements et d'une citation aléatoire à partir de 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"...

J'ai voté contre la réponse précédente car cela a fonctionné pour moi, mais ce n'est qu'une suggestion si vous ne voulez pas vous soucier de vos configurations. ~ PAIX!

sqliteframework d'entité

3
PixelSyndicate