Campi sottostanti
I campi sottostanti consentono a Entity Framework di leggere e/o scrivere in un campo anziché in una proprietà. Ciò può essere utile quando si usa l'incapsulamento nella classe per limitare l'uso di e/o migliorare la semantica per l'accesso ai dati dal codice dell'applicazione, ma il valore deve essere letto da e/o scritto nel database senza usare tali restrizioni/miglioramenti.
Configurazione di base
Per convenzione, i campi seguenti verranno individuati come campi sottostanti per una determinata proprietà (elencati in ordine di precedenza).
<camel-cased property name>
_<camel-cased property name>
_<property name>
m_<camel-cased property name>
m_<property name>
Nell'esempio seguente la Url
proprietà è configurata in modo che _url
abbia come campo sottostante:
public class Blog
{
private string _url;
public int BlogId { get; set; }
public string Url
{
get { return _url; }
set { _url = value; }
}
}
Si noti che i campi di backup vengono individuati solo per le proprietà incluse nel modello. Per altre informazioni sulle proprietà incluse nel modello, vedere Inclusione e esclusione di proprietà.
È anche possibile configurare i campi sottostanti usando un'annotazione dati o l'API Fluent, ad esempio se il nome del campo non corrisponde alle convenzioni precedenti:
public class Blog
{
private string _validatedUrl;
public int BlogId { get; set; }
[BackingField(nameof(_validatedUrl))]
public string Url
{
get { return _validatedUrl; }
}
public void SetUrl(string url)
{
// put your validation code here
_validatedUrl = url;
}
}
Accesso a campi e proprietà
Per impostazione predefinita, EF leggerà e scriverà sempre nel campo sottostante, presupponendo che sia stato configurato correttamente e non userà mai la proprietà . Ef supporta tuttavia anche altri modelli di accesso. Ad esempio, l'esempio seguente indica a EF di scrivere nel campo sottostante solo durante la materializzazione e di usare la proprietà in tutti gli altri casi:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Url)
.HasField("_validatedUrl")
.UsePropertyAccessMode(PropertyAccessMode.PreferFieldDuringConstruction);
}
Per il set completo di opzioni supportate, vedere l'enumerazione PropertyAccessMode.
Proprietà solo campo
È anche possibile creare una proprietà concettuale nel modello che non dispone di una proprietà CLR corrispondente nella classe di entità, ma usa invece un campo per archiviare i dati nell'entità. Questo è diverso dalle proprietà shadow, in cui i dati vengono archiviati nello strumento di rilevamento delle modifiche, anziché nel tipo CLR dell'entità. Le proprietà solo campo vengono comunemente usate quando la classe di entità usa metodi anziché proprietà per ottenere/impostare valori o nei casi in cui i campi non devono essere esposti affatto nel modello di dominio ,ad esempio chiavi primarie.
È possibile configurare una proprietà solo campo specificando un nome nell'API Property(...)
:
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property("_validatedUrl");
}
}
public class Blog
{
private string _validatedUrl;
public int BlogId { get; set; }
public string GetUrl()
{
return _validatedUrl;
}
public void SetUrl(string url)
{
using (var client = new HttpClient())
{
var response = client.GetAsync(url).Result;
response.EnsureSuccessStatusCode();
}
_validatedUrl = url;
}
}
EF tenterà di trovare una proprietà CLR con il nome specificato o un campo se non viene trovata una proprietà. Se non vengono trovati né una proprietà né un campo, verrà impostata una proprietà shadow.
Potrebbe essere necessario fare riferimento a una proprietà solo campo dalle query LINQ, ma tali campi sono in genere privati. È possibile usare il EF.Property(...)
metodo in una query LINQ per fare riferimento al campo :
var blogs = db.blogs.OrderBy(b => EF.Property<string>(b, "_validatedUrl"));