Campos de suporteBacking Fields

Observação

Esse recurso é novo no EF Core 1.1.This feature is new in EF Core 1.1.

Campos de suporte permitem que o EF para leitura e/ou gravar em um campo em vez de uma propriedade.Backing fields allow EF to read and/or write to a field rather than a property. Isso pode ser útil ao encapsulamento na classe está sendo usado para restringir o uso de e/ou aprimorar a semântica de acesso aos dados pelo código do aplicativo, mas o valor deve ser de leitura de e/ou gravado no banco de dados sem usar essas restrições / aprimoramentos.This can be useful when encapsulation in the class is being used to restrict the use of and/or enhance the semantics around access to the data by application code, but the value should be read from and/or written to the database without using those restrictions/enhancements.

ConvençõesConventions

Por convenção, os campos a seguir serão descobertos como campos de suporte para uma determinada propriedade (listados em ordem de precedência).By convention, the following fields will be discovered as backing fields for a given property (listed in precedence order). Campos só são descobertos para propriedades que são incluídas no modelo.Fields are only discovered for properties that are included in the model. Para obter mais informações no qual as propriedades são incluídas no modelo, consulte incluir e excluir propriedades.For more information on which properties are included in the model, see Including & Excluding Properties.

  • _<camel-cased property name>
  • _<property name>
  • m_<camel-cased property name>
  • m_<property name>
public class Blog
{
    private string _url;

    public int BlogId { get; set; }

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

Quando um campo de backup é configurado, o EF gravará diretamente a esse campo quando materializar as instâncias de entidade do banco de dados (em vez de usar o setter da propriedade).When a backing field is configured, EF will write directly to that field when materializing entity instances from the database (rather than using the property setter). Se o EF precisa ler ou gravar o valor em outros momentos, ele usará a propriedade se possível.If EF needs to read or write the value at other times, it will use the property if possible. Por exemplo, se o EF precisa para atualizar o valor para uma propriedade, ele usará o setter da propriedade se algum tiver sido definido.For example, if EF needs to update the value for a property, it will use the property setter if one is defined. Se a propriedade é somente leitura, ele gravará para o campo.If the property is read-only, then it will write to the field.

Anotações de dadosData Annotations

Campos de backup não podem ser configurado com anotações de dados.Backing fields cannot be configured with data annotations.

API fluenteFluent API

Você pode usar a API Fluent para configurar um campo de suporte para uma propriedade.You can use the Fluent API to configure a backing field for a property.

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

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

public class Blog
{
    private string _validatedUrl;

    public int BlogId { get; set; }

    public string Url
    {
        get { return _validatedUrl; }
    }

    public void SetUrl(string url)
    {
        using (var client = new HttpClient())
        {
            var response = client.GetAsync(url).Result;
            response.EnsureSuccessStatusCode();
        }

        _validatedUrl = url;
    }
}

Controlar quando o campo é usadoControlling when the field is used

Você pode configurar quando o EF usa o campo ou propriedade.You can configure when EF uses the field or property. Consulte a PropertyAccessMode enum para as opções com suporte.See the PropertyAccessMode enum for the supported options.

modelBuilder.Entity<Blog>()
    .Property(b => b.Url)
    .HasField("_validatedUrl")
    .UsePropertyAccessMode(PropertyAccessMode.Field);

Campos sem uma propriedadeFields without a property

Você também pode criar uma propriedade conceitual em seu modelo que não tem uma propriedade CLR correspondente na classe de entidade, mas em vez disso, usa um campo para armazenar os dados na entidade.You can also create a conceptual property in your model that does not have a corresponding CLR property in the entity class, but instead uses a field to store the data in the entity. Isso é diferente de propriedades de sombra, onde os dados são armazenados no Rastreador de alteração.This is different from Shadow Properties, where the data is stored in the change tracker. Isso normalmente seria usado se a classe de entidade usa métodos para obter/definir valores.This would typically be used if the entity class uses methods to get/set values.

Você pode dar o nome do campo no EF o Property(...) API.You can give EF the name of the field in the Property(...) API. Se não houver nenhuma propriedade com o nome fornecido, o EF procurará um campo.If there is no property with the given name, then EF will look for a field.

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

Você também pode optar por dar um nome diferente do nome do campo de propriedade.You can also choose to give the property a name, other than the field name. Esse nome é usado ao criar o modelo, mais notavelmente, ele será usado para o nome da coluna que é mapeado para o banco de dados.This name is then used when creating the model, most notably it will be used for the column name that is mapped to in the database.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property<string>("Url")
        .HasField("_validatedUrl");
}

Quando não há nenhuma propriedade na classe de entidade, você pode usar o EF.Property(...) método em uma consulta LINQ para fazer referência à propriedade que é conceitualmente parte do modelo.When there is no property in the entity class, you can use the EF.Property(...) method in a LINQ query to refer to the property that is conceptually part of the model.

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