Sia in EF Core che in EF6, invocando il getter della proprietà 'Date' (vedi sotto) si ottiene il valore corretto, tuttavia si noti la leggera differenza tra i due: in EF Core il setter non viene mai chiamato!
Questo è il mio modello:
public class MyModel
{
private DateTime _Date;
private bool dateTimeHasBeenSet = false;
public DateTime Date
{
get
{
return _Date;
}
set
{
dateTimeHasBeenSet = true;
_Date = value;
}
}
}
Questo è il mio modo di recuperare un singolo oggetto:
//Entity Framework 6
using (Ef6Context context = new Ef6Context())
{
var m = context.MyModels.First();
// m.dateTimeHasBeenSet is true
}
//Entity Framework Core
using (EfCoreContext context = new EfCoreContext())
{
var m = context.MyModels.First();
// m.dateTimeHasBeenSet is false
}
Il nucleo EF inizializza il campo di backup anziché la proprietà (tramite la riflessione)? questo non viola l'incapsulamento?
Sto migrando del codice da EF6 a EF Core e vorrei davvero evitare di sprecare tempo nel richiamare manualmente la logica dietro ogni setter ...
EDIT: Chiedere la domanda mi ha fatto provare qualcosa di particolare, se rinominavo il mio campo di backup da _Property a qualsiasi altra cosa come _PropertyX (in questo esempio sarebbe _DateX) magicamente il mio setter è invocato da EF Core!
Con EF Core abbiamo una nozione di Backing Fields:
I campi di supporto consentono a EF di leggere e / o scrivere in un campo anziché in una proprietà.
Quando EF individua per convenzione la presenza di un campo di supporto per la tua proprietà, utilizzerà quel campo invece della tua proprietà per materializzare la tua entità. Solo dopo che l'entità è stata materializzata e se EF deve aggiornare l'entità userà la proprietà se possibile (quando la proprietà non è di sola lettura) altrimenti continuerà a utilizzare il campo di supporto.
Puoi dire a EF Core di usare sempre la tua proprietà quando materializzi la tua entità facendo il codice seguente (possibile solo con Fluent API):
modelBuilder.Entity<MyModel>()
.Property(b => b.Date)
.HasField("_Date")
.UsePropertyAccessMode(PropertyAccessMode.Property);
Per saperne di più sui Backing Fields vai qui .
Se si desidera applicare questa configurazione a tutte le proprietà del modello, è possibile utilizzare il metodo dell'istanza UsePropertyAccessMode
di ModelBuilder
come di seguito:
modelBuilder.UsePropertyAccessMode(PropertyAccessMode.Property);