Entity Framework 6 con un campo Database generato non funziona sull'inserto. Da quanto ho letto dopo aver contrassegnato una colonna come DatabaseGenerated, EF non tenterà di inserire / aggiornare nulla in quel campo, che è particolarmente importante nel mio caso perché i campi sul database sono colonne calcolate da SQL Server e non solo predefinite valori, che è quello che ho visto in molte domande simili su Stack Overflow / Google.
Definizione della colonna (utilizzando una funzione definita dall'utente nella colonna calcolata):
ALTER TABLE dbo.MyModel ADD [TotalUnits] AS ([dbo].[CalculateTotalUnits]([Id]));
Definizione EF:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public decimal TotalUnits { get; private set; }
E poi sto solo facendo un
var myNewModel = new MyModel();
DbContext.MyModels.Add(myNewModel);
DbContext.SaveChanges();
Che dà:
System.Data.SqlClient.SqlException: impossibile inserire il valore NULL nella colonna "TotalUnits", tabella "MyDatabase.dbo.MyModel"; la colonna non consente null. INSERT fallisce.
Perché EF sta cercando di inserire un valore NULL
in una colonna calcolata e come posso dirlo di no?
Risulta quando si eseguono test di integrazione EF è stato configurato per utilizzare le Migrazioni automatiche anziché le nostre migrazioni. Poiché le colonne calcolate venivano aggiunte in uno script SQL personalizzato durante il metodo Up
di una migrazione, le colonne non erano in realtà colonne computed
durante i test, ma erano infatti generate da EF come campi decimal
regolari (non annullabili). Quindi provare ad aggiungere un nuovo modello al contesto stava facendo in modo che EF inserisse NULL
in quelle colonne e facesse esplodere.
La soluzione è di eseguire effettivamente le migrazioni nei test di integrazione. Una volta che la colonna viene effettivamente calcolata, EF smette di seguirlo.