Morten Frederiksen
Morten Frederiksen

Reputation: 5165

EF6/SQL Server Compact, code-based configuration

I'm trying to move my EF6 configuration from myexe.exe.config to code as a workaround for the empty DbProviderFactories node in machine.config-issue (described here: https://stackoverflow.com/a/24273922/600559). I don't want to change the machine.config file.

I have read the Code-Based Configuration (EF6 onwards).

I have tried implementations like this: https://stackoverflow.com/a/23130602/600559, however I cannot get it to work. Does anyone have a working EF6/SQL CE/code-based configuration solution?

Here's my my changes (from a working .config solution to a code based solution): New class added:

public class DatabaseConfiguration : DbConfiguration
{
    public DatabaseConfiguration()
    {
        SetExecutionStrategy("System.Data.SqlServerCe.4.0", () => new DefaultExecutionStrategy());
        SetProviderFactory("System.Data.SqlServerCe.4.0", new SqlCeProviderFactory());
        SetProviderServices("System.Data.SqlServerCe.4.0", SqlCeProviderServices.Instance);
    }
}

Then the system.data and entityFramework node in the .config-file is removed.

Now this works, however the machine.config files is read: If a have the <DbProviderFactories/> in machine.config I get this exception:

Exception

So the real problem is not that the code based configuration does not work, the problem is that the machine.config configuration is still being read and causes issues. Anyone knows how to solve this?

Upvotes: 2

Views: 828

Answers (1)

Morten Frederiksen
Morten Frederiksen

Reputation: 5165

Found a solution. Implementing a IDbProviderFactoryResolver that does not read from the machine.config file:

  public class CodeBasedDatabaseConfiguration : DbConfiguration
  {
    public CodeBasedDatabaseConfiguration()
    {
      SetExecutionStrategy("System.Data.SqlServerCe.4.0", () => new DefaultExecutionStrategy());
      SetProviderFactory("System.Data.SqlServerCe.4.0", new SqlCeProviderFactory());
      SetProviderServices("System.Data.SqlServerCe.4.0", SqlCeProviderServices.Instance);
      SetProviderFactoryResolver(new CodeBasedDbProviderFactoryResolver());
    }
  }

  internal class CodeBasedDbProviderFactoryResolver : IDbProviderFactoryResolver
  {
    private readonly DbProviderFactory sqlServerCeDbProviderFactory = new SqlCeProviderFactory();

    public DbProviderFactory ResolveProviderFactory(DbConnection connection)
    {
      var connectionType = connection.GetType();
      var assembly = connectionType.Assembly;
      if (assembly.FullName.Contains("System.Data.SqlServerCe"))
      {
        return sqlServerCeDbProviderFactory;
      }
      if (assembly.FullName.Contains("EntityFramework"))
      {
        return EntityProviderFactory.Instance;
      }
      return null;
    }
  }

Upvotes: 2

Related Questions