[英]SQLite & Entity Framework 6 “The underlying data provider failed to open”
當我的Winforms應用程序到達第一個Entity Framework數據“請求”時,出現以下錯誤。
消息:基礎提供程序無法打開。
InnerException:數據源不能為空。
我的連接字符串是動態構建的,可滿足用戶的%appdata%
目錄路徑。 我在第一次運行時構建它,並在構建后使用連接字符串更新app.config
。 處理此的代碼如下:
public void ConstructEntityFrameworkConnectionString(string dbFileName)
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.ConnectionStrings.ConnectionStrings["RemManagerDBEntities"] == null)
{
// Specify the provider name, server and database.
var provider = "System.Data.SQLite.EF6";
var providerName = "System.Data.EntityClient";
var attacheddbfilename = dbFileName;
// Initialize the connection string builder for the underlying provider.
SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder {
AttachDBFilename = attacheddbfilename,
IntegratedSecurity = true,
MultipleActiveResultSets = true,
ConnectTimeout = 30,
ApplicationName = "RemManagerDBEntities"
};
// Build the SqlConnection connection string.
string providerString = sqlBuilder.ToString();
// Initialize the EntityConnectionStringBuilder.
EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder {
Provider = provider,
ProviderConnectionString = providerString,
Metadata = @"res://*/EntityFramework.RemManagerDBModel.csdl|res://*/EntityFramework.RemManagerDBModel.ssdl|res://*/EntityFramework.RemManagerDBModel.msl"
};
var cs = new ConnectionStringSettings("RemManagerDBEntities", entityBuilder.ConnectionString, providerName);
if (config.ConnectionStrings.ConnectionStrings["RemManagerDBEntities"] == null)
{
config.ConnectionStrings.ConnectionStrings.Add(cs);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("connectionStrings");
}
}
}
它創建的示例連接字符串:
metadata=res://*/EntityFramework.RemManagerDBModel.csdl|res://*/EntityFramework.RemManagerDBModel.ssdl|res://*/EntityFramework.RemManagerDBModel.msl; provider=System.Data.SQLite.EF6; provider connection string="AttachDbFilename=C:\Users\MacbookPro\AppData\Roaming\RemManager\Datasource\RemManagerDB.db; Integrated Security=True; MultipleActiveResultSets=True; Connect Timeout=30; Application Name=RemManagerDBEntities"
該方法被稱為program.cs文件中main方法的一部分。
static void Main()
{
var conController = new ConnectionController();
conController.ConstructEntityFrameworkConnectionString($"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\RemManager\\Datasource\\RemManagerDB.db");
// Start the application
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new RemManager());
}
我已經安裝了以下NuGet軟件包:
最初,我根據以下站點的設置過程對第二個鏈接進行了修改。
https://www.codeproject.com/Tips/1056400/Setting-up-SQLite-and-Entity-Framework-Code-First
https://github.com/ErikEJ/SqlCeToolbox/wiki/EF6-workflow-with-SQLite-DDEX-provider
下面是我通過實體框架對數據庫進行調用的示例。 單步執行代碼時,異常從db.tblGroups.Select
行開始。
public class GroupController : IGroup
{
public List<tblGroup> SelectAllGroups()
{
using (var db = new RemManagerDBEntities())
{
return db.tblGroups.Select(g => g).ToList();
}
}
...
}
難題的最后一部分是app.config。 當前配置如下所示。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<!-- See Datasource.ConnectionController for the connection string builder.-->
</connectionStrings>
<entityFramework>
<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" />
</providers>
</entityFramework>
<appSettings>
<add key="databaseFilePath" value="" />
<add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
</providers>
</roleManager>
</system.web>
<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" />
<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>
</configuration>
對於其他而言,實體框架正在從數據庫優先配置開始工作。 我也在運行Entity Framework 6.2和SQLite 1.0.106.0。
我已經盡力在其他站點上找到有效的解決方案,以滿足我將Entity Framework和SQLite結合在一起的事實,但是我還沒有提出太多建議。 當我把SQLite排除在方程之外時,我仍然無法提出很多建議。 我發現的更好的問題之一是在這里 ,但我已經按照建議的答案推薦了。
除了localdb之外,我之前也有類似的問題。 該應用程序以前一直在localdb上工作,但是由於我一直在努力使該應用程序更加獨立和用戶友好(例如,安裝后無需手動修改exe.config),因此此問題已經開始。
任何建議將不勝感激。
您不能將SqlConnectionStringBuilder與SQLite一起使用,而應改用SQLiteConnectionStringBuilder,並將DataSource屬性設置為數據庫文件名
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.