Remove EF dependencies without using the Myconfiguration class

Asked

Viewed 237 times

3

I am trying to create an application by removing all EF dependencies and leaving only the necessary layers: Repository and Applying. I did a small project to test the operation before applying in the actual design to avoid complications, however, the only way I could run this project was with the use of the class Myconfiguration

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

It is possible to remove EF dependencies without using this class and without returning the exception?

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.

Follow the example code:

Class Context

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; }
    }
}

Code from the Repository layer 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" />
  <!-- 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>

package of the Repository layer

<?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.config app 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>

package of layer Application

<?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>

1 answer

2


Depends.

The Entity Framework requires at least one data access provider. As 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, of course the provider will be another. See examples of settings 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 at startup, you would have to increment your configuration class to receive the provider parameters dynamically.

A suggestion would be:

public class MyConfiguration : DbConfiguration
{
    public MyConfiguration(String providerInvariantName, DbProviderServices dbProviderService)
    {
        SetProviderServices(providerInvariantName, dbProviderService);
    }
}
  • You mean by making a different implementation of the Myconfiguration class, but still using it? Would you have any suggested implementation you could post?

  • @Kellysoares I edited the answer.

  • Gypsy, the second constructor parameter is Idbdependencyresolver dbProviderService even?

  • Yes, it is. The interface is more generic.

  • I am unable to use it, it returns me two errors: The best overloaded method match for 'System.Data.Entity.DbConfiguration.Setproviderservices(string, System.Data.Entity.Core.Common.Dbproviderservices)' has some invalid Arguments and the error Argument 2: cannot Convert from 'System.Data.Entity.Infrastructure.Dependencyresolution.Idbdependendencyresolver' to 'System.Data.Entity.Core.Common.Dbproviderservices'

  • Okay, I guess we’ll have to use the same object. I updated the answer.

  • With Object it is not. That’s for sure.

  • The problem is being in the second parameter of type Dbproviderservices

  • I don’t understand your problem now.

  • 1

    I closed the visual studio after doing the clean and it worked. Thanks Gypsy!

Show 6 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.