无法使用 EF6 让 SQLite 在 VS2019 中工作

Pau*_*ems 3 sqlite entity-framework-6 visual-studio-2019

我一整天都在努力让它工作,但到目前为止还没有运气。

我正在为 .NETv4.7.2 构建一个 WinForm 应用程序,我会将这个应用程序分发给客户端,稍后可能需要更新它。因此,我想启用自动迁移。我也想使用CodeFirst。

我正在使用 @ErikEJ 的 SQLiteCeToolbox 并按照http://erikej.blogspot.com/2018/03/using-entity-framework-6-and-sqlite.html中提到的方式安装所有内容

我的工具箱设置:

Version 4.7.644.0

SQL Server Compact 4.0 in GAC - Yes - 4.0.8482.1
SQL Server Compact 4.0 DbProvider - Yes

SQL Server Compact 4.0 DDEX provider - No
SQL Server Compact 4.0 Simple DDEX provider - Yes


SQL Server Compact 3.5 in GAC - Yes - 3.5.8080.0
SQL Server Compact 3.5 DbProvider - Yes

SQL Server Compact 3.5 DDEX provider - No

Sync Framework 2.1 SqlCe 3.5 provider - No

SQLite ADO.NET Provider included: 1.0.110.0
SQLite EF6 DbProvider in GAC - Yes
System.Data.SQLite DDEX provider - No
SQLite Simple DDEX provider - Yes
Run Code Online (Sandbox Code Playgroud)

我的包裹:

<package id="EntityFramework" version="6.3.0" targetFramework="net472" />
<package id="log4net" version="2.0.8" targetFramework="net472" />
<package id="SQLite.EF6.Migrations-Extensible" version="1.0.106" targetFramework="net472" />
<package id="System.Data.SQLite" version="1.0.112.0" targetFramework="net472" />
<package id="System.Data.SQLite.Core" version="1.0.112.0" targetFramework="net472" />
<package id="System.Data.SQLite.EF6" version="1.0.112.0" targetFramework="net472" />
<package id="System.Data.SQLite.Linq" version="1.0.112.0" targetFramework="net472" />
Run Code Online (Sandbox Code Playgroud)

还有我的App.config

<add name="MySqliteConnection" connectionString="Data Source=D:\dev\foo\bar\db\Mydb.sqlite" providerName="System.Data.SQLite.EF6" />

<entityFramework>
  <providers>
    <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" />
 </DbProviderFactories>
</system.data>
Run Code Online (Sandbox Code Playgroud)

我已经尝试了 App.confg 的多种变体,但我不断收到如下错误:

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.
Run Code Online (Sandbox Code Playgroud)

不确定它是否相关,但这是我的服务,我在我的(单元)测试中调用它:

public List<UploadedFile> GetAllUploadedFiles()
{
    using var db = new ApplicationContext();
    return db.UploadedFiles.ToList();
}
Run Code Online (Sandbox Code Playgroud)

这是我的应用程序上下文:

public class ApplicationContext : DbContext
{
    static ApplicationContext()
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<ApplicationContext, ContextMigrationConfiguration>(true));
    }

    public ApplicationContext(DbConnection connection) : base(connection, false)
    { }

    public ApplicationContext() : this(MakeConnection())
    {
    }

    private static DbConnection MakeConnection()
    {
        const string dbFilename = "MyDb.sqlite";

        var filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), 
            "db", dbFilename);
        if (File.Exists(filePath)) return new SQLiteConnection($"Data Source={filePath};Version=3;");
        // First time, copy empty db from installer. TODO: might be better to create empty db instead:
        var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "db", dbFilename);
        if (!File.Exists(path)) throw new FileNotFoundException("Cannot find " + path, path);
        File.Copy(path, filePath, true);
        return  new SQLiteConnection($"Data Source={filePath};Version=3;");
    }

    public DbSet<UploadedFile> UploadedFiles { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在安装SQLite.EF6.Migrations-Extensible和使用之前MigrateDatabaseToLatestVersion我得到了一些更多的进展。我的测试确实有效,但未创建表。

所以很可能我混合了太多不同的方法。我愿意接受另一种方法(当然如果它有效的话),该方法将使用代码优先并自动更新我的客户端的数据库。

Pau*_*ems 5

我终于让它工作了。这个 app.config 在 VS2017 和 VS2019 中为我工作:

<connectionStrings>
  <add name="MySqliteConnection" connectionString="Data Source=D:\dev\foo\bar\db\MyDb.sqlite" providerName="System.Data.SQLite.EF6" />
</connectionStrings>
<entityFramework>
  <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
    <parameters>
      <parameter value="v13.0" />
    </parameters>
  </defaultConnectionFactory>
  <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.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>
<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" culture="neutral" />
      <bindingRedirect oldVersion="0.0.0.0-1.0.112.0" newVersion="1.0.112.0" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name="System.Data.SQLite.EF6" publicKeyToken="db937bc2d44ff139" culture="neutral" />
      <bindingRedirect oldVersion="0.0.0.0-1.0.112.0" newVersion="1.0.112.0" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>
Run Code Online (Sandbox Code Playgroud)

我之所以能做到这一点,是因为我在 VS2017 中创建了一个新项目,没有单独的测试项目,并且在表单上有一个按钮来从数据库中获取一些数据。
之后,我又回到了更大的 VS2019 项目。修复了它的 App.config并且,这是最重要的部分,从我的测试项目中删除了 App.config 并将其链接到主项目中。

希望这对其他人也有帮助。我一天的大部分时间都花在这上面;(