entity-frameworksql-server-cemicrosoft-sync-frameworksql-server-ce-4sql-server-ce-3.5

Entity Framework looks for ADO.NET provider SqlServerCe.3.5 instead of 4.0


I am using SQL Server CE 4.0 along with entity framework 6.0. Everythings work fine until I wanted to enable a N-Tier syncing mechanism with a remote database using a WCF service and the Sync Framework 2.1.

I followed this tutorial and use the JTune's workaround to overcome the issue that the SyncFramework 2.1 and SQLSErverCompactCE 4.0 compatibility is not supported. Which is simply a runtime binding redirect in app.config for System.Data.SqlServerCE.dll 4.0.0

Then I get the following App.config file

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlCeConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="System.Data.SqlServerCe.4.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <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>
  <connectionStrings>
    <add name="Entities" connectionString="metadata=res://*/Persistence.Model1.csdl|res://*/Persistence.Model1.ssdl|res://*/Persistence.Model1.msl;provider=System.Data.SqlServerCe.4.0;provider connection string=&quot;data source=|DataDirectory|\XXXX.sdf&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Data.SqlServerCe" publicKeyToken="89845DCD8080CC91" culture="neutral"/>
        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
<system.data>
  <DbProviderFactories>
    <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>
</configuration>

It works fine on some configuration but may fail with the following error.

 No Entity Framework provider found for the ADO.NET provider with invariant name 'System.Data.SqlServerCe.3.5'. Make sure the provider is registered in the 'entityFramework' section of the application config file. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.

Remark that the solution provided in this question is not viable, because in my situation, I really need the binding redirect to use SyncFramework.

Is there a way to tell entity framework not to look for a SQL Server CE 3.5 provider and only for the 4.0?


Solution

  • I think I got this. When SQL Server CE 3.5 is installed on the machine then its added to the DbProviders in the machine.config and depending on its position regarding the 4.0 version you may have the failure (see my comment above). It looks like the app.config lets you the possibility to remove a DbProviderFactory. I added the following line in my app.config and the problem seems to be resolved

    <system.data>
      <DbProviderFactories>
        <remove invariant="System.Data.SqlServerCe.3.5" />
      </DbProviderFactories>
    </system.data>