Eigenschappen van schaduw- en indexeerfunctie

Schaduweigenschappen zijn eigenschappen die niet zijn gedefinieerd in uw .NET-entiteitsklasse, maar die zijn gedefinieerd voor dat entiteitstype in het EF Core-model. De waarde en status van deze eigenschappen worden uitsluitend gehandhaafd in de Change Tracker. Schaduweigenschappen zijn handig wanneer er gegevens in de database zijn die niet mogen worden weergegeven op de toegewezen entiteitstypen.

Eigenschappen van de indexeerfunctie zijn eigenschappen van het entiteitstype, die worden ondersteund door een indexeerfunctie in .NET-entiteitsklasse. Ze kunnen worden geopend met behulp van de indexeerfunctie op de .NET-klasse-exemplaren. Hiermee kunt u ook extra eigenschappen toevoegen aan het entiteitstype zonder de CLR-klasse te wijzigen.

Schaduweigenschappen van refererende sleutel

Schaduweigenschappen worden het vaakst gebruikt voor eigenschappen van refererende sleutels, waarbij ze volgens conventie worden toegevoegd aan het model wanneer er geen refererende sleuteleigenschap is gevonden of expliciet is geconfigureerd. De relatie wordt vertegenwoordigd door navigatie-eigenschappen, maar in de database wordt deze afgedwongen door een beperking voor refererende sleutels en wordt de waarde voor de kolom met refererende sleutels opgeslagen in de bijbehorende schaduweigenschap.

De eigenschap krijgt de naam <navigation property name><principal key property name> (de navigatie op de afhankelijke entiteit, die verwijst naar de principal-entiteit, wordt gebruikt voor de naamgeving). Als de naam van de principale sleuteleigenschap begint met de naam van de navigatie-eigenschap, dan is de naam alleen <principal key property name>. Als er geen navigatie-eigenschap voor de afhankelijke entiteit is, wordt de naam van het hoofdtype samen met de naam van de primaire of alternatieve sleuteleigenschap gebruikt <principal type name><principal key property name>.

De volgende codevermelding resulteert bijvoorbeeld in een BlogId schaduweigenschap die wordt geïntroduceerd in de Post entiteit:

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

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    // Since there is no CLR property which holds the foreign
    // key for this relationship, a shadow property is created.
    public Blog Blog { get; set; }
}

Schaduweigenschappen configureren

U kunt de Fluent-API gebruiken om schaduweigenschappen te configureren. Zodra u de overbelasting van Property<TProperty>(String)de tekenreeks hebt aangeroepen, kunt u een van de configuratie-aanroepen koppelen die u voor andere eigenschappen zou doen. In het volgende voorbeeld, omdat Blog er geen CLR-eigenschap met de naam LastUpdatedheeft, wordt er een schaduweigenschap gemaakt:

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

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .Property<DateTime>("LastUpdated");
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

Als de naam die aan de Property methode wordt opgegeven overeenkomt met de naam van een bestaande eigenschap (een schaduweigenschap of een eigenschap die is gedefinieerd in de entiteitsklasse), configureert de code die bestaande eigenschap in plaats van een nieuwe schaduweigenschap in te voeren.

Schaduweigenschappen openen

Waarden voor schaduweigenschappen kunnen worden verkregen en gewijzigd via de ChangeTracker API:

context.Entry(myBlog).Property("LastUpdated").CurrentValue = DateTime.Now;

Naar schaduweigenschappen kan worden verwezen in LINQ-query's via de EF.Property statische methode.

var blogs = context.Blogs
    .OrderBy(b => EF.Property<DateTime>(b, "LastUpdated"));

Schaduweigenschappen kunnen niet worden geopend na een query zonder bijhouden, omdat de geretourneerde entiteiten niet worden bijgehouden door de wijzigingentracker.

Eigenschappen van de indexeerfunctie configureren

U kunt de Fluent-API gebruiken om de eigenschappen van de indexeerfunctie te configureren. Zodra u de methode IndexerPropertyhebt aangeroepen, kunt u een van de configuratie-aanroepen koppelen die u voor andere eigenschappen zou gebruiken. In het volgende voorbeeld Blog is een indexeerfunctie gedefinieerd en wordt deze gebruikt om een indexeerfunctie-eigenschap te maken.

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

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>().IndexerProperty<DateTime>("LastUpdated");
    }
}

public class Blog
{
    private readonly Dictionary<string, object> _data = new Dictionary<string, object>();
    public int BlogId { get; set; }

    public object this[string key]
    {
        get => _data[key];
        set => _data[key] = value;
    }
}

Als de naam die aan de IndexerProperty methode is opgegeven overeenkomt met de naam van een bestaande indexeerfunctieeigenschap, wordt die bestaande eigenschap geconfigureerd door de code. Als het entiteitstype een eigenschap heeft die wordt ondersteund door een eigenschap in de entiteitsklasse, wordt er een uitzondering gegenereerd omdat de eigenschappen van de indexeerfunctie alleen toegankelijk zijn via de indexeerfunctie.

De eigenschappen van de indexeerfunctie kunnen worden verwezen in LINQ-query's via de EF.Property statische methode, zoals hierboven wordt weergegeven of met behulp van de eigenschap CLR-indexeerfunctie.

Entiteitstypen eigenschappenverzameling

Entiteitstypen die alleen indexeerfuncties bevatten, worden entiteitstypen voor eigenschappenverzamelingen genoemd. Deze entiteitstypen hebben geen schaduweigenschappen en EF maakt in plaats daarvan indexeerfuncties. Momenteel wordt alleen Dictionary<string, object> ondersteund als een eigenschapsverzamelingstype. Het moet worden geconfigureerd als een entiteitstype voor het gedeelde type met een unieke naam en de bijbehorende DbSet eigenschap moet worden geïmplementeerd met behulp van een Set aanroep.

internal class MyContext : DbContext
{
    public DbSet<Dictionary<string, object>> Blogs => Set<Dictionary<string, object>>("Blog");

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.SharedTypeEntity<Dictionary<string, object>>(
            "Blog", bb =>
            {
                bb.Property<int>("BlogId");
                bb.Property<string>("Url");
                bb.Property<DateTime>("LastUpdated");
            });
    }
}

Eigenschappenverzameling-entiteitstypen kunnen worden gebruikt waar een normaal entiteitstype wordt gebruikt, inclusief als een eigendom-entiteitstype. Ze hebben echter wel bepaalde beperkingen: