无法确定类型为“System.Data.Sqlite.SqliteFactory”的提供程序工厂的提供程序名称。

34

我想在我的Web API项目中使用SQLite Entity Framework,但它总是无法正常工作。

这是我的开发环境:

  1. Visual Studio 2013,.NET Framework 4.5

  2. SQLite包版本为1.0.97,我安装了以下软件包:

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

  3. EntityFramework为6.1.3

我得到的异常如下:

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

这是我的Web.config文件:

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

我可以通过 Visual Studio 工具中的“连接到数据库”来连接 SQLite 数据库文件,也可以使用 Code First 生成实体。

但是我无法正常获取数据。

以下是我的代码:

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

2个回答

67

我自己找到了答案,但仍然不知道根本原因,现在它可以工作了。 我更改了Webconfig,这是使我的项目工作的Webconfig。

我添加了一个提供程序即“System.Data.Sqlite”,请注意它的类型与“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" />

这里是所有的配置。
 <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>

1
我只看了你的web.config,但是我错过了你使用的基本构造函数重载。我一直在使用public MyContext() : base(FactoryConnection.CreateSQLite())当我切换到public MyContext() : base("MySQLiteConnection")然后它就可以工作了。你的问题给了我答案。谢谢! - jokab

22

那是一个非常棒的回答,zhnglicho!

除了将提供程序和 DbProviderFactories 放置在 app.config 或 web.config 中之外,另一个选择是编写您自己的 ProviderFactories 并在 DbContext 的实现中使用它。

所需引用:

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;

配置类:

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

将这段代码放在你的构造函数中:

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

我已经对这两种方法(包括这个和zhnglicho的方法)运行了单元测试,没有发现速度差异。

调试输出(从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"...

这个答案对我有用,所以我点了赞,但如果你不想改变配置文件,这只是一个建议。 ~平安!


我无法让app.config起作用,但这个可以。谢谢! - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接