Compartilhar via


Provedor do SQL Server do Entity Framework 6 com base em Microsoft.Data.SqlClient

Esse provedor do Entity Framework 6 é um provedor de substituição para o provedor interno do SQL Server.

Esse provedor depende do provedor de ADO.NET Microsoft.Data.SqlClient moderno, que inclui as seguintes vantagens em relação ao driver usado no momento:

  • Cliente atual recebendo suporte completo em contraste com System.Data.SqlClient, que está no modo de manutenção
  • Suporta novos recursos do SQL Server, incluindo suporte para o protocolo de cliente aprimorado do SQL Server 2022 (TDS8)
  • Dá suporte à maioria dos métodos de autenticação do Azure Active Directory
  • Dá suporte ao Always Encrypted com .NET

Observe que esse provedor é uma atualização somente de runtime e não funcionará com as ferramentas existentes do Visual Studio.

O build mais recente desse pacote está disponível no NuGet

Configuração

Há várias maneiras de configurar o Entity Framework para usar esse provedor.

Você pode registrar o provedor no código usando um atributo:

[DbConfigurationType(typeof(MicrosoftSqlDbConfiguration))]
public class SchoolContext : DbContext
{
    public SchoolContext() : base()
    {
    }

    public DbSet<Student> Students { get; set; }
}

Se você tiver várias classes herdando de DbContext em sua solução, adicione o atributo DbConfigurationType a todas elas.

Ou você pode usar o método SetConfiguration antes de qualquer chamada de acesso a dados:

 DbConfiguration.SetConfiguration(new MicrosoftSqlDbConfiguration());

Ou adicione as seguintes linhas à classe DbConfiguration derivada existente:

SetProviderFactory(MicrosoftSqlProviderServices.ProviderInvariantName, Microsoft.Data.SqlClient.SqlClientFactory.Instance);
SetProviderServices(MicrosoftSqlProviderServices.ProviderInvariantName, MicrosoftSqlProviderServices.Instance);
// Optional
SetExecutionStrategy(MicrosoftSqlProviderServices.ProviderInvariantName, () => new MicrosoftSqlAzureExecutionStrategy());

Você também pode usar a configuração baseada em 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" />    
    </configSections>
    <entityFramework>
        <providers>
            <provider invariantName="Microsoft.Data.SqlClient" type="System.Data.Entity.SqlServer.MicrosoftSqlProviderServices, Microsoft.EntityFramework.SqlServer" />
        </providers>
    </entityFramework>
    <system.data>
        <DbProviderFactories>
           <add name="SqlClient Data Provider"
             invariant="Microsoft.Data.SqlClient"
             description=".NET Framework Data Provider for SqlServer"
             type="Microsoft.Data.SqlClient.SqlClientFactory, Microsoft.Data.SqlClient" />
        </DbProviderFactories>
    </system.data>
</configuration>

Se você usar App.Config com um aplicativo .NET 6 ou posterior, deverá remover a seção <system.data> acima e registrar o DbProviderFactory no código uma vez:

DbProviderFactories.RegisterFactory(MicrosoftSqlProviderServices.ProviderInvariantName, Microsoft.Data.SqlClient.SqlClientFactory.Instance);

Uso de EDMX

Se você usar um arquivo EDMX, atualize o nome Provider:

<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
  <edmx:Runtime>
    <edmx:StorageModels>
      <Schema Namespace="ChinookModel.Store" Provider="Microsoft.Data.SqlClient" >

Para usar o arquivo EDMX com o designer do Visual Studio, você deve alternar o nome do provedor de volta para System.Data.SqlClient

Atualize também o nome do provedor dentro da cadeia de conexão EntityConnection -provider=Microsoft.Data.SqlClient

 <add 
    name="Database" 
    connectionString="metadata=res://*/EFModels.csdl|res://*/EFModels.ssdl|res://*/EFModels.msl;provider=Microsoft.Data.SqlClient;provider connection string=&quot;data source=server;initial catalog=mydb;integrated security=True;persist security info=True;" 
    providerName="System.Data.EntityClient" 
 />

Alterações de código

Para usar o provedor em uma solução existente, algumas alterações de código são necessárias (conforme necessário).

using System.Data.SqlClient; =>using Microsoft.Data.SqlClient;

using Microsoft.SqlServer.Server; =>using Microsoft.Data.SqlClient.Server;

As seguintes classes foram renomeada para evitar conflitos com classes que usam System.Data.SqlClient no provedor existente do SQL Server:

SqlAzureExecutionStrategy =>MicrosoftSqlAzureExecutionStrategy

SqlDbConfiguration =>MicrosoftSqlDbConfiguration

SqlProviderServices =>MicrosoftSqlProviderServices

SqlServerMigrationSqlGenerator =>MicrosoftSqlServerMigrationSqlGenerator

SqlSpatialServices =>MicrosoftSqlSpatialServices

SqlConnectionFactory =>MicrosoftSqlConnectionFactory

LocalDbConnectionFactory =>MicrosoftLocalDbConnectionFactory

Problemas conhecidos

Serviço de Aplicativo do Azure com o .NET Framework e a configuração de cadeias de conexão

Se você usar o Serviço de Aplicativo do Azure com o .NET Framework e o recurso de configuração de cadeias de conexão, poderá encontrar problemas de runtime, pois a configuração da cadeia de conexão ProviderName neste cenário é codificada para System.Data.SqlClient.

A solução é usar uma classe MicrosoftSqlDbConfiguration derivada como esta:

public class AppServiceConfiguration : MicrosoftSqlDbConfiguration
{
    public AppServiceConfiguration()
    {
        SetProviderFactory("System.Data.SqlClient", Microsoft.Data.SqlClient.SqlClientFactory.Instance);
        SetProviderServices("System.Data.SqlClient", MicrosoftSqlProviderServices.Instance);
        SetExecutionStrategy("System.Data.SqlClient", () => new MicrosoftSqlAzureExecutionStrategy());
    }
}

Em seguida, use essa classe derivada na configuração baseada em código descrita acima.

EntityFramework.dll instalado no GAC

Se uma versão mais antiga do EntityFramework.dll estiver instalada no GAC (Cache de Assembly Global) do .NET Framework, você poderá receber este erro:

The 'PrimitiveTypeKind' attribute is invalid - The value 'HierarchyId' is invalid according to its datatype

A solução é remover o .dll do GAC. Os assemblies EF6 nunca devem ser instalados no GAC.