Champs de stockageBacking Fields

Note

Cette fonctionnalité est une nouveauté dans EF Core 1.1.This feature is new in EF Core 1.1.

Champs de stockage permettent EF lire et/ou écrire à un champ au lieu d’une propriété.Backing fields allow EF to read and/or write to a field rather than a property. Cela peut être utile lors de l’encapsulation de la classe est utilisée pour limiter l’utilisation d’et/ou d’améliorer la sémantique autour de l’accès aux données par code d’application, mais la valeur doit être lus ou écrite à la base de données sans l’aide de ces restrictions / améliorations.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.

ConventionsConventions

Par convention, les champs suivants seront détectés en tant que la sauvegarde des champs pour une propriété donnée (répertoriées dans l’ordre de priorité).By convention, the following fields will be discovered as backing fields for a given property (listed in precedence order). Les champs sont détectés uniquement pour les propriétés qui sont incluses dans le modèle.Fields are only discovered for properties that are included in the model. Pour plus d’informations sur lequel les propriétés sont incluses dans le modèle, consultez notamment & exclusion des propriétés.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; }
    }
}

Lorsqu’un champ de stockage est configuré, EF écrit directement dans ce champ lors de la matérialisation des instances d’entité à partir de la base de données (plutôt qu’à l’aide de l’accesseur Set de propriété).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). Si EF doit lire ou écrire la valeur à d’autres moments, il utilise la propriété si possible.If EF needs to read or write the value at other times, it will use the property if possible. Par exemple, si EF doit mettre à jour la valeur d’une propriété, il utilise la méthode setter de propriété si celle-ci est définie.For example, if EF needs to update the value for a property, it will use the property setter if one is defined. Si la propriété est en lecture seule, puis elle écrit dans le champ.If the property is read-only, then it will write to the field.

Annotations de donnéesData Annotations

Champs de stockage ne peut pas être configuré avec des annotations de données.Backing fields cannot be configured with data annotations.

API FluentFluent API

Vous pouvez utiliser l’API Fluent pour configurer un champ de stockage pour une propriété.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;
    }
}

Contrôle lorsque le champ est utilisé.Controlling when the field is used

Vous pouvez configurer quand EF utilise le champ ou la propriété.You can configure when EF uses the field or property. Consultez le PropertyAccessMode enum pour les options prises en charge.See the PropertyAccessMode enum for the supported options.

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

Champs sans une propriétéFields without a property

Vous pouvez également créer une propriété conceptuelle dans votre modèle qui n’a pas d’une propriété CLR correspondante dans la classe d’entité, mais utilise à la place d’un champ pour stocker les données dans l’entité.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. Cela est différent de occulter les propriétés, où les données sont stockées dans le traceur de modifications.This is different from Shadow Properties, where the data is stored in the change tracker. Cela doit généralement être utilisé si la classe d’entité utilise des méthodes pour obtenir/définir des valeurs.This would typically be used if the entity class uses methods to get/set values.

Vous pouvez donner à EF le nom du champ dans le Property(...) API.You can give EF the name of the field in the Property(...) API. S’il n’existe aucune propriété portant le nom donné, puis EF recherchera un champ.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;
    }
}

Vous pouvez également attribuer la propriété à un nom, autre que le nom du champ.You can also choose to give the property a name, other than the field name. Ce nom est ensuite utilisé lors de la création du modèle, notamment il sera utilisé pour le nom de colonne qui est mappé à la base de données.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");
}

Lorsqu’il n’y a aucune propriété dans la classe d’entité, vous pouvez utiliser la EF.Property(...) méthode dans une requête LINQ pour faire référence à la propriété qui fait partie du modèle.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"));