c# – Remove EF dependencies without using the MyConfiguration class

Question:

I'm trying to create an application removing all EF's dependencies and leaving only the necessary layers: Repository and Application . I did a small project to test the operation before applying it to the real project to avoid complications, however, the only way I was able to run this project was using the MyConfiguration class

public class MyConfiguration : DbConfiguration
{
    public MyConfiguration()
    {
        SetProviderServices(
            System.Data.Entity.SqlServer.SqlProviderServices.ProviderInvariantName,
            System.Data.Entity.SqlServer.SqlProviderServices.Instance);
    }
}

É possível remover as dependências do EF sem o uso dessa classe e sem retornar a exceção?

An exception of type ‘System.InvalidOperationException’ occurred in EntityFramework.dll but was not handled in user code Additional
information: No Entity Framework provider found for the ADO.NET
provider with invariant name ‘System.Data.SqlClient’. Make sure the
provider is registered in the ‘entityFramework’ section of the
application config file.

Segue o código exemplo:

Classe Contexto

using MvcNorthwindExemplo.Dominio;
using System.Data.Entity;

namespace MvcNorthwindExemplo.Repositorio
{
    public class DBNorthwindContext : DbContext
    {
        public DBNorthwindContext()
            : base(@"Data Source=(local); Initial Catalog=NorthwindExemplo; Integrated Security=true")
        {            
        }

        public DbSet<Regiao> Regioes { get; set; }
    }
}

Repository layer app.config code

<?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" />
  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

Repository layer package

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="EntityFramework" version="6.1.3" targetFramework="net451" />
  <package id="Glimpse" version="1.8.6" targetFramework="net451" />
  <package id="Glimpse.Ado" version="1.7.3" targetFramework="net451" />
  <package id="Glimpse.AspNet" version="1.9.2" targetFramework="net451" />
  <package id="Glimpse.EF6" version="1.6.5" targetFramework="net451" />
  <package id="Glimpse.Mvc5" version="1.5.3" targetFramework="net451" />
</packages>

Application Class

using MvcNorthwindExemplo.Dominio;
using MvcNorthwindExemplo.Repositorio;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;

namespace MvcNorthwindExemplo.Aplicacao
{
    public class RegiaoAplicacao
    {
        public DBNorthwindContext db { get; set; }

    public RegiaoAplicacao()
    {
        db = new DBNorthwindContext();
    }

    public void AddRegiao(Regiao regiao)
    {
        db.Regioes.Add(regiao);
        db.SaveChanges();
    }

    public void UpdateRegiao(Regiao regiao)
    {
        db.Entry(regiao).State = EntityState.Modified;
        db.SaveChanges();
    }

    public void Excluir(long? id)
    {
        var regiao = db.Regioes.Where(r => r.RegiaoID == id).FirstOrDefault();
        if (regiao != null)
        {
            db.Regioes.Remove(regiao);
            db.SaveChanges();
        }
    }

    public Regiao GetRegiaoFind(long id)
    {
        return GetRegiaoAll().Where(r => r.RegiaoID == id).FirstOrDefault();
    }

    public IEnumerable<Regiao> GetRegiaoAll()
    {
        return db.Regioes.ToList();
    }        
}
}

Application layer app.config code

<?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" />
  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> </configSections>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

Application layer package

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="EntityFramework" version="6.1.3" targetFramework="net451" />
  <package id="Glimpse" version="1.8.6" targetFramework="net451" />
  <package id="Glimpse.Ado" version="1.7.3" targetFramework="net451" />
  <package id="Glimpse.AspNet" version="1.9.2" targetFramework="net451" />
  <package id="Glimpse.EF6" version="1.6.5" targetFramework="net451" />
  <package id="Glimpse.Mvc5" version="1.5.3" targetFramework="net451" />
</packages>

Answer:

It depends.

The Entity Framework asks for at least one data access provider. Since in this case you are using SQL Server LocalDb for database access, the Entity Framework needs this dependency with System.Data.SqlClient . If it is another database, naturally the provider will be another. See example configurations for other databases:

SQL Server

  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>

SQL Server LocalDb

  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>

MySQL

  <entityFramework>
    <defaultConnectionFactory type="MySql.Data.Entity.MySqlConnectionFactory, MySql.Data.Entity.EF6"></defaultConnectionFactory>
    <providers>
      <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6"></provider>
    </providers>
  </entityFramework>

Oracle

  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="Oracle.ManagedDataAccess.Client" type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />
    </providers>
  </entityFramework>

Firebird

<entityFramework>
    <defaultConnectionFactory type="FirebirdSql.Data.EntityFramework6.FbConnectionFactory, EntityFramework.Firebird" />
    <providers>
        <provider invariantName="FirebirdSql.Data.FirebirdClient" type="FirebirdSql.Data.EntityFramework6.FbProviderServices, EntityFramework.Firebird" />
    </providers>
</entityFramework>

PostgreSQL

<entityFramework>
  <defaultConnectionFactory type="Npgsql.NpgsqlFactory, Npgsql" />
  <providers>
    <provider invariantName="Npgsql" type="Npgsql.NpgsqlServices, Npgsql.EntityFramework" />
  </providers>
<entityFramework>

Now, to make the Entity Framework completely agnostic on startup, you would have to increment your configuration class to dynamically receive the provider parameters.

A suggestion would be:

public class MyConfiguration : DbConfiguration
{
    public MyConfiguration(String providerInvariantName, DbProviderServices dbProviderService)
    {
        SetProviderServices(providerInvariantName, dbProviderService);
    }
}
Scroll to Top