Sto provando a utilizzare il codice Entity Framework per un semplice progetto di database e mi imbatto in un problema che non riesco a capire.
Ho notato che EF stava impostando l’ID dei miei tavoli automaticamente aumentando di 1 ogni volta, ignorando completamente il valore inserito manualmente per quel campo. Dopo alcune ricerche, ho capito che il modo giusto per disabilitare questo comportamento è:
modelBuilder.Entity().Property(e => e.EventID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Comunque ora sto ricevendo questo errore e non ho idea del perché:
Eccezione non gestita: System.Data.Entity.Infrastructure.DbUpdateException: si è verificato un errore durante l’aggiornamento delle voci. Vedi l’eccezione interna per i dettagli. —
System.Data.UpdateException: si è verificato un errore durante l’aggiornamento delle voci. Vedi l’eccezione interna per i dettagli. —> System.Data.SqlClient.SqlException: imansible inserire il valore esplicito per la colonna Identity nella tabella “Events” quando IDENTITY_INSERT è impostato su OFF.
- parola chiave non supportata origine dati
- Relazione di auto-referenza many-to-many
- LINQ, imansible creare un valore costante di tipo XXX. In questo contesto sono supportati solo tipi primitivi o tipi di enumerazione
- Puoi dire a JSON.Net di serializzare DateTime come Utc anche se non specificato?
- Imansible trovare il nome del tipo o spazio dei nomi 'DbContext'
Se è utile, ecco la class POCO in questione:
public class Event { [Key, Required] public int EventID { get; set; } public string EventType { get; set; } //TODO: Event Type Table later on public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public virtual ICollection Matches { get; set; } public virtual ICollection EventParticipation { get; set; } }
Grazie in anticipo.
Per impostazione predefinita, Entity Framework presuppone che una chiave primaria intera sia generata dal database (equivalente all’aggiunta di HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
o alla chiamata Property(e => e.EventID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
in Fluent API.
Se osservi la migrazione che crea la tabella dovresti vedere questo:
CreateTable( "dbo.Events", c => new { EventID = c.Int(nullable: false, identity: true), //etc }) .PrimaryKey(t => t.EventID );
Quindi è stato modificato il modello utilizzando l’API Fluent in DatabaseGenerated.None
. EF lo inserisce nella migrazione:
AlterColumn("dbo.Events", "EventID", c => c.Int(nullable: false, identity: false))
E lo sql generato è questo:
ALTER TABLE [dbo].[Events] ALTER COLUMN [EventID] [int] NOT NULL
Che in realtà fa accovacciarsi. Eliminare l’IDENTITÀ da una colonna non è banale. È necessario eliminare e ricreare la tabella o creare una nuova colonna, quindi è necessario copiare i dati e correggere le chiavi esterne. Quindi non è sorprendente che EF non lo stia facendo per te.
Devi trovare il modo migliore per farlo da solo. È ansible ripristinare le migrazioni su 0 e re-impalcature da zero ora che è stato specificato DatabaseGeneratedOption.None
oppure è ansible modificare manualmente la migrazione per eliminare e ricreare la tabella.
Oppure puoi rilasciare e ricreare la colonna:
DropColumn("Customer", "CustomerId"); AddColumn("Customer", "CustomerId", c => c.Long(nullable: false, identity: false));
MODIFICA O è ansible triggersre / distriggersre l’id quadro con un’operazione di migrazione personalizzata
Dal momento che preferisco gli attributi, qui l’alternativa per motivi di completezza:
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; }