Generazione di valori di SQL Server
Questa pagina descrive in dettaglio la configurazione e i modelli di generazione di valori specifici per il provider SQL Server. È consigliabile leggere prima la pagina generale sulla generazione di valore.
Colonne IDENTITY
Per convenzione, le colonne numeriche configurate per avere i relativi valori generati nel componente aggiuntivo vengono configurate come colonne IDENTITY di SQL Server.
Valore di inizializzazione e incremento
Per impostazione predefinita, le colonne IDENTITY iniziano a 1 (seed) e incrementano di 1 ogni volta che viene aggiunta una riga (incremento). È possibile configurare un seme e un incremento diversi nel modo seguente:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.BlogId)
.UseIdentityColumn(seed: 10, increment: 10);
}
Inserimento di valori espliciti nelle colonne IDENTITY
Per impostazione predefinita, SQL Server non consente l'inserimento di valori espliciti nelle colonne IDENTITY. A tale scopo, è necessario abilitare manualmente IDENTITY_INSERT
prima di chiamare SaveChangesAsync()
, come indicato di seguito:
using (var context = new ExplicitIdentityValuesContext())
{
context.Blogs.Add(new Blog { BlogId = 100, Url = "http://blog1.somesite.com" });
context.Blogs.Add(new Blog { BlogId = 101, Url = "http://blog2.somesite.com" });
await context.Database.OpenConnectionAsync();
try
{
await context.Database.ExecuteSqlRawAsync("SET IDENTITY_INSERT dbo.Blogs ON");
await context.SaveChangesAsync();
await context.Database.ExecuteSqlRawAsync("SET IDENTITY_INSERT dbo.Blogs OFF");
}
finally
{
await context.Database.CloseConnectionAsync();
}
}
Nota
Abbiamo una richiesta di funzionalità nel backlog per automatizzare questa operazione all'interno del provider di SQL Server.
Sequenze
In alternativa alle colonne IDENTITY, è possibile usare sequenze standard. Questo può essere utile in vari scenari; Ad esempio, è possibile che più colonne disegnino i valori predefiniti da una singola sequenza.
SQL Server consente di creare sequenze e usarle come descritto in dettaglio nella pagina generale sulle sequenze. Spetta a te configurare le proprietà per l'uso delle sequenze tramite HasDefaultValueSql()
.
GUID
Per le chiavi primarie GUID, il provider genera automaticamente valori sequenziali ottimali, analogamente alla funzione NEWSEQUENTIALID di SQL Server. La generazione del valore sul client è più efficiente in alcuni scenari. Ad esempio, non è necessario un ulteriore round trip al database per ottenere il valore generato dal database, quando viene inserita anche un'entità dipendente che fa riferimento a tale chiave.
Per fare in modo che Entity Framework generi gli stessi valori GUID sequenziali per le proprietà non chiave, configurarli come indicato di seguito:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>().Property(b => b.Guid).HasValueGenerator(typeof(SequentialGuidValueGenerator));
}
Rowversions
SQL Server ha il tipo di dati rowversion
, che cambia automaticamente ogni volta che la riga viene aggiornata. Ciò rende molto utile come token di concorrenza, per la gestione dei casi in cui la stessa riga viene aggiornata contemporaneamente da più transazioni.
Per comprendere appieno i token di concorrenza e come usarli, leggere la pagina dedicata in conflitti di concorrenza. Per mappare una proprietà byte[]
a una colonna rowversion
, configurare come segue:
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[Timestamp]
public byte[] Version { get; set; }
}