Il mio obiettivo è rendere Entity Framework 2 piacevole con il seguente codice:
public class Foo
{
public Guid Id { get; } // This should NOT change
public string NotRequiredProperty {get; set;}
public Foo(Guid id) => Id = id;
private Foo() { } // Empty constructor is necessary for EF Core I believe?
}
Ho letto questo post sul blog che dice che è possibile fare quanto segue:
// Class
private Guid _id;
public Guid Id => _id;
// Configuration
modelBuilder.Entity<Foo>()
.Property(b => b.Id)
.UsePropertyAccessMode(PropertyAccessMode.FieldDuringConstruction);
Quale potrebbe funzionare.
L'unico miglioramento che vedo qui è che sono obbligato a dichiarare esplicitamente un campo di backing privato anche se un { get; }
significa che uno è stato creato implicitamente.
Come posso far funzionare EF Core con JUST a { get; }
(e ovviamente alcune configurazioni di entità richieste)
Quello che stai chiedendo è possibile in generale con EF Core 2.1 introdotto tipi di entità con costruttori con funzionalità di parametri . Non hai più bisogno del costruttore vuoto - EF Core sarà in grado di utilizzare il costruttore con il parametro Guid id
.
Tuttavia ci sono due limitazioni che si applicano alla proprietà Id
. In primo luogo, si tratta di una proprietà di sola lettura (da cui è sostenuta da readonly
campo che può essere impostata da un costruttore). L'equivalente nell'esempio del campo di backing esplicito sarebbe se lo definissi come private readonly Guid _id;
. Quindi la configurazione di esempio NON funzionerà.
La sezione della documentazione per le proprietà di sola lettura dice:
Una volta che le proprietà vengono impostate tramite il costruttore, può avere senso renderne alcune di sola lettura. EF Core lo supporta, ma ci sono alcune cose da tenere a mente:
- Le proprietà senza setter non sono mappate per convenzione. (In questo modo si tende a mappare le proprietà che non dovrebbero essere mappate, come le proprietà calcolate).
- L'utilizzo di valori chiave generati automaticamente richiede una proprietà chiave che è di lettura-scrittura, poiché il valore chiave deve essere impostato dal generatore di chiavi quando si inseriscono nuove entità.
Presta attenzione al secondo punto, perché questo è il secondo problema. La proprietà Id
per convenzione è un PK e i PK di tipo Guid
e numerico per convenzione sono generati automaticamente .
Quindi è necessario scegliere tra due opzioni: rendere l' Id
non di sola lettura aggiungendo private set;
come suggerito nel link, o (che è la risposta della domanda "Come posso far funzionare EF Core con JUST a { get; }
" ) renderlo non generato automaticamente usando la seguente configurazione fluente:
modelBuilder.Entity<Foo>()
.Property(e => e.Id)
.ValueGeneratedNever();