AUTOINCREMENT di solito non deve essere utilizzato in SQLite. Anche senza questa parola chiave, gli ID generati automaticamente funzionano.
Tuttavia, la chiave primaria intera è dichiarata come AUTOINCREMENT quando si utilizza Entity Framework Core (come da 2.1.3) e SQLite. c'è un modo per evitarlo?
Ho provato ad aggiungere l'attributo [DatabaseGenerated(DatabaseGeneratedOption.None)]
alla proprietà della chiave primaria dell'entità, ma questo disabilita del tutto la generazione automatica delle chiavi e devo impostarlo manualmente per ciascun inserto. Altrimenti, EFC tenta di inserire con un Id = 0
esplicito Id = 0
.
Quindi ho bisogno che venga trattato come un database generato su insert, vorrei solo evitare la parola chiave AUTOINCREMENT non necessaria. C'è un modo per fare questo?
Ecco alcuni esempi di codice C #:
using System;
using Microsoft.EntityFrameworkCore;
namespace Experiments
{
public class Entity
{
public long Id { get; set; }
public string Text { get; set; }
}
public class Context : DbContext
{
public DbSet<Entity> Entities { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=temp.sqlite");
}
}
public static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static void Main()
{
using (var context = new Context())
{
context.Database.EnsureCreated();
}
}
}
}
Questo creerà un database simile a questo, se visualizzato con DB Browser per SQLite:
Preferirei non avere la chiave primaria dichiarata come AUTOINCREMENT, che crea anche la tabella sqlite_sequence. SQLite può generare chiavi senza quella parola chiave, e lo fa più semplice e veloce.
Per quanto posso dire, il problema è causato dal seguente codice nella classe SqliteMigrationsAnnotationProvider
corrente:
if (property.ValueGenerated == ValueGenerated.OnAdd
&& property.ClrType.UnwrapNullableType().IsInteger()
&& !HasConverter(property))
{
yield return new Annotation(SqliteAnnotationNames.Autoincrement, true);
}
che sta forzando la classe SqliteMigrationsSqlGenerator
a includere AUTOINCREMENT
.
Non so perché, suppongo che sia un errore avanzato, ma è meglio chiedere nel tracker dei problemi.
Guardando il codice, sembra che l'impostazione del convertitore di valori falsi possa impedirlo e può essere utilizzata come soluzione temporanea:
modelBuilder.Entity<Entity>()
.Property(e => e.Id)
.HasConversion(v => v, v => v);
Definita la classe del modello come sotto. Quindi non mapperai la colonna Id e userai un'altra colonna come PK.
[NotMapped]
public override int Id
{
get
{
return PKColumn;
}
set
{
PKColumn = value;
}
}
[Key]
public virtual int PKColumn { get; set; }