如何在配置文件注册Firebird ADO.NET Provider解决EF6连接报错
这个问题我之前部署Firebird嵌入式应用时也踩过坑——未安装Firebird Net Provider的机器上,系统没法找到FirebirdSql.Data.FirebirdClient这个ADO.NET Provider的注册信息,所以才会抛出那个错误。要解决这个问题,你需要在app.config里显式注册该Provider,同时确保依赖的程序集随应用一起发布。
具体修改步骤
1. 添加<system.data>节点注册Provider
在你的configuration根节点下,添加一个system.data节点,里面通过DbProviderFactories注册Firebird的ADO.NET Provider,告诉.NET框架这个Provider对应的程序集位置和版本信息:
<system.data> <DbProviderFactories> <remove invariant="FirebirdSql.Data.FirebirdClient" /> <add name="FirebirdClient Data Provider" invariant="FirebirdSql.Data.FirebirdClient" description=".NET Framework Data Provider for Firebird" type="FirebirdSql.Data.FirebirdClient.FbProviderFactory, FirebirdSql.Data.FirebirdClient, Version=6.0.0.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c" /> </DbProviderFactories> </system.data>
注意:这里的
Version要和你实际使用的FirebirdSql.Data.FirebirdClient.dll版本一致,PublicKeyToken是固定的(3750abcc3150b00c),如果版本不对可能会导致加载失败。
2. 确保依赖程序集随应用发布
你需要把以下几个dll文件和你的应用程序exe放在同一目录下(未安装Provider的机器没有这些文件):
- FirebirdSql.Data.FirebirdClient.dll
- EntityFramework.Firebird.dll
- fbclient.dll(就是你连接字符串里指定的嵌入式客户端库)
修改后的完整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" /> <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <section name="ScheduleWorkbench.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" /> </sectionGroup> </configSections> <!-- 新增的Provider注册节点 --> <system.data> <DbProviderFactories> <remove invariant="FirebirdSql.Data.FirebirdClient" /> <add name="FirebirdClient Data Provider" invariant="FirebirdSql.Data.FirebirdClient" description=".NET Framework Data Provider for Firebird" type="FirebirdSql.Data.FirebirdClient.FbProviderFactory, FirebirdSql.Data.FirebirdClient, Version=6.0.0.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c" /> </DbProviderFactories> </system.data> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /> </startup> <entityFramework> <defaultConnectionFactory type="FirebirdSql.Data.EntityFramework6.FbConnectionFactory, EntityFramework.Firebird" /> <providers> <provider invariantName="FirebirdSql.Data.FirebirdClient" type="FirebirdSql.Data.EntityFramework6.FbProviderServices, EntityFramework.Firebird" /> </providers> </entityFramework> <connectionStrings> <add name="DbModel" connectionString="character set=UTF8;data source=localhost;initial catalog=H:\Projects\ScheduleWorkbench\ScheduleWorkbench\Firebird\SCHEDULE.FDB;user id=SYSDBA;password=masterkey;role=SYSDBA;server type=1;client library=H:\Projects\ScheduleWorkbench\ScheduleWorkbench\Firebird\fbclient.dll" providerName="FirebirdSql.Data.FirebirdClient" /> </connectionStrings> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Syncfusion.Shared.Wpf" publicKeyToken="3d67ed1f87d44c89" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-15.2451.0.40" newVersion="15.2451.0.40" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
原理说明
正常安装Firebird Net Provider时,它会在系统的machine.config文件中注册FirebirdSql.Data.FirebirdClient这个Provider,这样.NET框架就能找到对应的程序集。但在未安装Provider的机器上,machine.config里没有这个注册信息,所以必须在应用自己的app.config里手动添加,让.NET知道去哪里加载该Provider的程序集。
内容的提问来源于stack exchange,提问作者Nineor

