Pola zapasowe
Pola zapasowe umożliwiają programowi EF odczytywanie i/lub zapisywanie w polu, a nie na właściwości. Może to być przydatne, gdy hermetyzacja w klasie jest używana do ograniczania użycia i/lub ulepszania semantyki wokół dostępu do danych za pomocą kodu aplikacji, ale wartość powinna być odczytywana z i/lub zapisywana w bazie danych bez używania tych ograniczeń/ulepszeń.
Konfiguracja podstawowa
Zgodnie z konwencją następujące pola zostaną odnalezione jako pola zapasowe dla danej właściwości (wymienione w kolejności pierwszeństwa).
<camel-cased property name>
_<camel-cased property name>
_<property name>
m_<camel-cased property name>
m_<property name>
W poniższym przykładzie Url
właściwość jest skonfigurowana jako _url
pole zapasowe:
public class Blog
{
private string _url;
public int BlogId { get; set; }
public string Url
{
get { return _url; }
set { _url = value; }
}
}
Należy pamiętać, że pola kopii zapasowej są wykrywane tylko dla właściwości uwzględnionych w modelu. Aby uzyskać więcej informacji na temat właściwości uwzględnionych w modelu, zobacz Dołączanie i wykluczanie właściwości.
Pola kopii zapasowej można również skonfigurować przy użyciu adnotacji danych lub interfejsu API Fluent, np. jeśli nazwa pola nie odpowiada powyższym konwencjom:
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;
}
}
Dostęp do pola i właściwości
Domyślnie program EF zawsze odczytuje i zapisuje w polu zaplecza — zakładając, że został prawidłowo skonfigurowany — i nigdy nie będzie używać właściwości . Jednak program EF obsługuje również inne wzorce dostępu. Na przykład w poniższym przykładzie program EF nakazuje programowi EF zapisywanie w polu zapasowym tylko podczas materializowania i używanie właściwości we wszystkich innych przypadkach:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Url)
.HasField("_validatedUrl")
.UsePropertyAccessMode(PropertyAccessMode.PreferFieldDuringConstruction);
}
Zobacz wyliczenie PropertyAccessMode, aby uzyskać pełny zestaw obsługiwanych opcji.
Właściwości tylko pola
Można również utworzyć właściwość koncepcyjną w modelu, która nie ma odpowiedniej właściwości CLR w klasie jednostek, ale zamiast tego używa pola do przechowywania danych w jednostce. Różni się to od właściwości cienia, gdzie dane są przechowywane w monitorze zmian, a nie w typie CLR jednostki. Właściwości tylko dla pól są często używane, gdy klasa jednostki używa metod zamiast właściwości do pobierania/ustawiania wartości lub w przypadkach, gdy pola nie powinny być uwidocznione w ogóle w modelu domeny (np. klucze podstawowe).
Właściwość tylko dla pola można skonfigurować, podając nazwę w interfejsie Property(...)
API:
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;
}
}
Program EF podejmie próbę znalezienia właściwości CLR o podanej nazwie lub polu, jeśli właściwość nie zostanie znaleziona. Jeśli nie zostanie znaleziona żadna właściwość ani pole, zamiast tego zostanie skonfigurowana właściwość w tle.
Może być konieczne odwołanie się do właściwości tylko dla pola z zapytań LINQ, ale takie pola są zwykle prywatne. Możesz użyć EF.Property(...)
metody w zapytaniu LINQ, aby odwołać się do pola:
var blogs = db.blogs.OrderBy(b => EF.Property<string>(b, "_validatedUrl"));