Condividi tramite


Provider Di Entity Framework 6 SQL Server basato su Microsoft.Data.SqlClient

Questo provider Entity Framework 6 è un provider sostitutivo per il provider SQL Server predefinito.

Questo provider dipende dal provider di ADO.NET Microsoft.Data.SqlClient moderno, che include i vantaggi seguenti rispetto al driver attualmente usato:

  • Il client corrente riceve il supporto completo a differenza di System.Data.SqlClient, che è in modalità di manutenzione
  • Supporta nuove funzionalità di SQL Server, incluso il supporto per il protocollo client avanzato di SQL Server 2022 (TDS8)
  • Supporta la maggior parte dei metodi di autenticazione di Azure Active Directory
  • Supporta Always Encrypted con .NET

Si noti che questo provider è un aggiornamento di sola esecuzione e non funziona con gli strumenti esistenti di Visual Studio.

La build più recente di questo pacchetto è disponibile in NuGet

Impostazione

Esistono diversi modi per configurare Entity Framework per l'uso di questo provider.

È possibile registrare il provider nel codice usando un attributo :

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

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

Se nella soluzione sono presenti più classi che ereditano da DbContext, aggiungere l'attributo DbConfigurationType a tutti.

In alternativa, è possibile usare il metodo SetConfiguration prima di qualsiasi chiamata di accesso ai dati:

 DbConfiguration.SetConfiguration(new MicrosoftSqlDbConfiguration());

In alternativa, aggiungere le righe seguenti alla classe DbConfiguration derivata esistente:

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

È anche possibile usare la configurazione basata su 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 si usa App.Config con un'app .NET 6 o successiva, è necessario rimuovere la <system.data> sezione precedente e registrare DbProviderFactory nel codice una sola volta:

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

Utilizzo EDMX

Se si usa un file EDMX, aggiornare il Provider nome:

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

Per usare il file EDMX con la finestra di progettazione di Visual Studio, è necessario ripristinare il nome del provider System.Data.SqlClient

Aggiornare anche il nome del provider all'interno del stringa di connessione 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" 
 />

Modifiche al codice

Per usare il provider in una soluzione esistente, sono necessarie alcune modifiche al codice (in base alle esigenze).

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

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

Le classi seguenti sono state rinominate per evitare conflitti con le classi che usano System.Data.SqlClient nel provider SQL Server esistente:

SqlAzureExecutionStrategy =>MicrosoftSqlAzureExecutionStrategy

SqlDbConfiguration =>MicrosoftSqlDbConfiguration

SqlProviderServices =>MicrosoftSqlProviderServices

SqlServerMigrationSqlGenerator =>MicrosoftSqlServerMigrationSqlGenerator

SqlSpatialServices =>MicrosoftSqlSpatialServices

SqlConnectionFactory =>MicrosoftSqlConnectionFactory

LocalDbConnectionFactory =>MicrosoftLocalDbConnectionFactory

Problemi noti

app Azure Servizio con configurazione di .NET Framework e stringa di connessione s

Se si usa app Azure Servizio con .NET Framework e la funzionalità di configurazione stringa di connessione s, è possibile riscontrare problemi di runtime, poiché l'impostazione ProviderName stringa di connessione in questo scenario è hardcoded su System.Data.SqlClient.

La soluzione consiste nell'usare una classe MicrosoftSqlDbConfiguration derivata come segue:

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

Usare quindi questa classe derivata nella configurazione basata sul codice descritta in precedenza.

EntityFramework.dll installato nella GAC

Se una versione precedente di EntityFramework.dll è installata nella GAC di .NET Framework (Global Assembly Cache), è possibile che venga visualizzato questo errore:

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

La soluzione consiste nel rimuovere il .dll dalla GAC. Gli assembly EF6 non devono mai essere installati nella GAC.