Sdílet prostřednictvím


Pomocná pole

Backing fields allow EF to read and/or write to a field than a property. To může být užitečné, když se zapouzdření ve třídě používá k omezení použití a/nebo vylepšení sémantiky týkající se přístupu k datům kódem aplikace, ale hodnota by měla být načtena nebo zapsána do databáze bez použití těchto omezení/vylepšení.

Základní konfigurace

Podle konvence budou následující pole zjištěna jako záložní pole pro danou vlastnost (uvedená v pořadí priority).

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

V následující ukázce je vlastnost nakonfigurovaná tak, Url aby měla _url jako záložní pole:

public class Blog
{
    private string _url;

    public int BlogId { get; set; }

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

Všimněte si, že backingová pole jsou zjištěna pouze pro vlastnosti, které jsou součástí modelu. Další informace o tom, které vlastnosti jsou součástí modelu, naleznete v tématu Zahrnutí a vyloučení vlastností.

Backingová pole můžete nakonfigurovat také pomocí datových poznámek nebo rozhraní Fluent API, například pokud název pole neodpovídá výše uvedeným konvencím:

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

Přístup k polím a vlastnostem

Ve výchozím nastavení ef vždy přečte a zapíše do backingového pole – za předpokladu, že je správně nakonfigurovaný – a vlastnost nikdy nepoužije. EF ale podporuje i jiné vzory přístupu. Například následující ukázka dává EF pokyn, aby zapisoval do backingového pole pouze při materializaci a aby tuto vlastnost používal ve všech ostatních případech:

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

Kompletní sadu podporovaných možností najdete v výčtu PropertyAccessMode.

Vlastnosti jen pro pole

V modelu můžete také vytvořit koncepční vlastnost, která nemá odpovídající vlastnost CLR ve třídě entity, ale místo toho používá pole k uložení dat v entitě. Liší se od stínových vlastností, kde jsou data uložena v sledování změn, nikoli v typu CLR entity. Vlastnosti jen pro pole se běžně používají, když třída entity používá metody místo vlastností k získání/nastavení hodnot nebo v případech, kdy pole by neměla být v doménovém modelu vůbec zpřístupněna (např. primární klíče).

Vlastnost jen pro pole můžete nakonfigurovat zadáním názvu v Property(...) rozhraní 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;
    }
}

EF se pokusí najít vlastnost CLR s daným názvem nebo pole, pokud se vlastnost nenajde. Pokud se nenajde žádná vlastnost ani pole, nastaví se místo toho stínová vlastnost.

Možná budete muset odkazovat na vlastnost jen pro pole z dotazů LINQ, ale tato pole jsou obvykle soukromá. Metodu EF.Property(...) v dotazu LINQ můžete použít k odkazování na pole:

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