Entity Framework使用Sqlite時的一些配置


前段時間試着用Entity Framework for Sqlite環境,發現了一些坑坑窪窪,記錄一下。

同時試了一下配置多種數據庫,包括Sqlite、Sql Server、Sql Server LocalDB、Sql Server Compact。

 

我建的demo項目結構以及通過NuGet安裝的包:

  

EFDemo.MultipleDB.UI引用了EFDemo.MutipleDB項目。

 

1. 遇到的異常1

The Entity Framework provider type 'System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SQLite.EF6' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.

我是是引用了Sqlite相關的dll了的(見下圖),但是發現生成后再EFDemo.MultipleDB.UI下的生成文件中沒有自動將這些dll拷貝過來。

2.

於是我將這些手動拷貝過來了。

 2. 遇到的異常2

剛才的異常沒了,又出現了一個異常。

The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.

這次在代碼里面加了這么一段,不用調用,只是在代碼里讓它存在:

        /// <summary>
        /// 解決provider不能自動加載的問題
        /// (不需要調用,放在這里即可)
        /// </summary>
        private static void FixProvidersNotAutoLoadProblem() 
        {
            var _ = typeof(System.Data.SQLite.EF6.SQLiteProviderFactory);
            var __ = typeof(System.Data.Entity.SqlServer.SqlProviderServices);
            var ___ = typeof(System.Data.Entity.SqlServerCompact.SqlCeProviderServices);
        }

3. 遇到的異常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.

Sqlite的那些包是通過NuGet安裝的,但是NuGet貌似沒有幫忙生成完整的配置,所以需要自己補上。

這里貼上的是完整的,注意紅色的是添加的:

  <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" />
      <remove invariant="System.Data.SqlServerCe.4.0" />
      <add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
    </DbProviderFactories>
  </system.data>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlCeConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="System.Data.SqlServerCe.4.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="System.Data.SqlServerCe.4.0" type="System.Data.Entity.SqlServerCompact.SqlCeProviderServices, EntityFramework.SqlServerCompact" />
    </providers>
  </entityFramework>

4. 雖然使用的是Code First,但是System.Data.SQLite.EF6是不能幫助我們自動生成數據庫的表結構的,需要手動創建。(當然,可以找找有沒有其他支持Sqlite的Migration的EF Provider)

 

OK了,到此這幾個坑算是填平了。

 

5. 設置DataDirectory

我的Sqlite的連接字符串是這樣寫的:

<add name="BloggingContext_SQLite" connectionString="Data Source=|DataDirectory|\Blogging_SQLite.db" providerName="System.Data.SQLite.EF6"/>

為了開發方便,我將數據庫文件放在了項目里面,這個樣子:

怎樣告訴連接字符串DataDirectory在這里呢?

        private static void SetDataDir() 
        {
            DirectoryInfo baseDir = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
            string data_dir = baseDir.FullName;
            if ((baseDir.Name.ToLower() == "debug" || baseDir.Name.ToLower() == "release")
                && (baseDir.Parent.Name.ToLower() == "bin"))
            {
                data_dir = Path.Combine(baseDir.Parent.Parent.FullName, "App_Data");
            }
            
            AppDomain.CurrentDomain.SetData("DataDirectory", data_dir);
        }

在程序初始化時調用。

 

附:

完整代碼在這里

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM