Freigeben über


Unterstützungsfelder

Unterstützungsfelder ermöglichen EF, aus einem Feld anstelle einer Eigenschaft zu lesen und/oder dort hinein zu schreiben. Dies kann nützlich sein, wenn die Kapselung in der Klasse verwendet wird, um im Umfeld des Zugriffs auf die Daten durch den Anwendungscode die Verwendung der Semantik einzuschränken und/oder die Semantik zu verbessern, aber der Wert aus der Datenbank gelesen und/oder in die Datenbank geschrieben werden sollte, ohne diese Einschränkungen/Verbesserungen zu verwenden.

Basiskonfiguration

Laut Konvention werden die folgenden Felder als Unterstützungsfelder für eine bestimmte Eigenschaft (nach Rangfolge aufgelistet) ermittelt.

  • <camel-cased property name>
  • _<camel-cased property name>
  • _<property name>
  • m_<camel-cased property name>
  • m_<property name>

Im folgenden Beispiel ist die Url-Eigenschaft so konfiguriert, dass sie _url als Unterstützungsfeld hat:

public class Blog
{
    private string _url;

    public int BlogId { get; set; }

    public string Url
    {
        get { return _url; }
        set { _url = value; }
    }
}

Beachten Sie, dass Unterstützungsfelder nur für Eigenschaften ermittelt werden, die im Modell enthalten sind. Weitere Informationen dazu, welche Eigenschaften im Modell enthalten sind, finden Sie unter Einschließen & Ausschließen von Eigenschaften.

Sie können Unterstützungsfelder auch mithilfe einer Datenanmerkung oder der Fluent-API konfigurieren, z. B. wenn der Feldname nicht den oben genannten Konventionen entspricht:

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;
    }
}

Feld- und Eigenschaftenzugriff

Standardmäßig liest EF immer aus dem Unterstützungsfeld und schreibt dort hinein – vorausgesetzt, eines wurde ordnungsgemäß konfiguriert – und verwendet niemals die Eigenschaft. EF unterstützt jedoch auch andere Zugriffsmuster. Im folgenden Beispiel wird EF z. B. angewiesen, nur während der Materialisierung in das Unterstützungsfeld zu schreiben und in allen anderen Fällen die Eigenschaft zu verwenden:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Url)
        .HasField("_validatedUrl")
        .UsePropertyAccessMode(PropertyAccessMode.PreferFieldDuringConstruction);
}

Den vollständigen Satz unterstützter Optionen finden Sie in der Enumeration PropertyAccessMode.

„Nur-Feld“-Eigenschaften

Sie können auch eine konzeptionelle Eigenschaft in Ihrem Modell erstellen, die nicht über eine entsprechende CLR-Eigenschaft in der Entitätsklasse verfügt, sondern stattdessen ein Feld verwendet, um die Daten in der Entität zu speichern. Dies unterscheidet sich von Schatteneigenschaften, bei denen die Daten in der Änderungsnachverfolgung gespeichert werden und nicht im CLR-Typ der Entität. „Nur-Feld“-Eigenschaften werden häufig verwendet, wenn die Entitätsklasse Methoden anstelle von Eigenschaften zum Abrufen/Festlegen von Werten verwendet, oder in Fällen, in denen Felder überhaupt nicht im Domänenmodell verfügbar gemacht werden sollen (z. B. Primärschlüssel).

Sie können eine „Nur-Feld“-Eigenschaft konfigurieren, indem Sie einen Namen in der Property(...)-API angeben:

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 versucht, eine CLR-Eigenschaft mit dem angegebenen Namen zu finden, oder ein Feld, wenn keine Eigenschaft gefunden wird. Wenn weder eine Eigenschaft noch ein Feld gefunden wird, wird stattdessen eine Schatteneigenschaft eingerichtet.

Möglicherweise müssen Sie von LINQ-Abfragen auf eine „Nur-Feld“-Eigenschaft verweisen, aber solche Felder sind in der Regel privat. Sie können die EF.Property(...)-Methode in einer LINQ-Abfrage verwenden, um auf das Feld zu verweisen:

var blogs = db.blogs.OrderBy(b => EF.Property<string>(b, "_validatedUrl"));