Schlüssellose EntitätstypenKeyless Entity Types

Hinweis

Diese Funktion wurde unter dem Namen der Abfrage Typen hinzugefügt.This feature was added under the name of query types. In EF Core 3,0 wurde das Konzept in schlüssellose Entitäts Typen umbenannt.In EF Core 3.0 the concept was renamed to keyless entity types. Die [Keyless] Daten Anmerkung wurde in efcore 5,0 verfügbar.The [Keyless] Data Annotation became available in EFCore 5.0.

Zusätzlich zu regulären Entitäts Typen kann ein EF Core Modell Schlüssel-Entitäts Typen enthalten, die verwendet werden können, um Datenbankabfragen für Daten auszuführen, die keine Schlüsselwerte enthalten.In addition to regular entity types, an EF Core model can contain keyless entity types , which can be used to carry out database queries against data that doesn't contain key values.

Definieren von schlüssellosen Entitäts TypenDefining Keyless entity types

Schlüssellose Entitäts Typen können entweder mithilfe der Daten Anmerkung oder der fließenden API definiert werden:Keyless entity types can be defined using either the Data Annotation or the Fluent API:

[Keyless]
public class BlogPostsCount
{
    public string BlogName { get; set; }
    public int PostCount { get; set; }
}

Merkmale von Keyless-Entitäts TypenKeyless entity types characteristics

Schlüssellose Entitäts Typen unterstützen viele der gleichen Zuordnungs Funktionen wie reguläre Entitäts Typen wie Vererbungs Zuordnung und Navigations Eigenschaften.Keyless entity types support many of the same mapping capabilities as regular entity types, like inheritance mapping and navigation properties. In relationalen speichern können Sie die Ziel Datenbankobjekte und-Spalten überfließende API-Methoden oder Daten Anmerkungen konfigurieren.On relational stores, they can configure the target database objects and columns via fluent API methods or data annotations.

Sie unterscheiden sich jedoch von regulären Entitäts Typen darin, dass Sie:However, they are different from regular entity types in that they:

  • Ein Schlüssel kann nicht definiert werden.Cannot have a key defined.
  • Werden nie nach Änderungen im dbcontext nachverfolgt und daher nie in der Datenbank eingefügt, aktualisiert oder gelöscht.Are never tracked for changes in the DbContext and therefore are never inserted, updated or deleted on the database.
  • Werden nie nach Konvention ermittelt.Are never discovered by convention.
  • Unterstützt nur eine Teilmenge der Navigations Zuordnungsfunktionen, insbesondere:Only support a subset of navigation mapping capabilities, specifically:
    • Sie werden möglicherweise nie als Prinzipal Ende einer Beziehung fungieren.They may never act as the principal end of a relationship.
    • Sie haben möglicherweise keine Navigation zu besitzende Entitäten.They may not have navigations to owned entities
    • Sie können nur Verweis Navigations Eigenschaften enthalten, die auf reguläre Entitäten verweisen.They can only contain reference navigation properties pointing to regular entities.
    • Entitäten können keine Navigations Eigenschaften für Entitäts Typen ohne Schlüssel enthalten.Entities cannot contain navigation properties to keyless entity types.
  • Muss mit einer [Keyless] Daten Anmerkung oder einem Methoden Befehl konfiguriert werden .HasNoKey() .Need to be configured with a [Keyless] data annotation or a .HasNoKey() method call.
  • Kann einer definierenden Abfrage zugeordnet werden.May be mapped to a defining query. Eine definierende Abfrage ist eine im Modell deklarierte Abfrage, die als Datenquelle für einen schlüssellosen Entitätstyp fungiert.A defining query is a query declared in the model that acts as a data source for a keyless entity type.

VerwendungsszenariosUsage scenarios

Einige der wichtigsten Verwendungs Szenarien für Typen von schlüssellosen Entitäten sind:Some of the main usage scenarios for keyless entity types are:

  • Fungieren als Rückgabetyp für unformatierte SQL-Abfragen.Serving as the return type for raw SQL queries.
  • Zuordnung zu Daten Bank Sichten, die keinen Primärschlüssel enthalten.Mapping to database views that do not contain a primary key.
  • Zuordnung zu Tabellen, für die kein Primärschlüssel definiert ist.Mapping to tables that do not have a primary key defined.
  • Zuordnung zu Abfragen, die im Modell definiert sind.Mapping to queries defined in the model.

Zuordnung zu DatenbankobjektenMapping to database objects

Die Zuordnung eines Entitäts Typs mit einer anderen Tastatur zu einem Datenbankobjekt erfolgt mithilfe der-oder-über ToTable ToView flüssigen API.Mapping a keyless entity type to a database object is achieved using the ToTable or ToView fluent API. Aus Sicht der EF Core ist das in dieser Methode angegebene Datenbankobjekt eine Sicht. Dies bedeutet, dass es als schreibgeschützte Abfrage Quelle behandelt wird und nicht das Ziel von Aktualisierungs-, Einfüge-oder Lösch Vorgängen sein kann.From the perspective of EF Core, the database object specified in this method is a view , meaning that it is treated as a read-only query source and cannot be the target of update, insert or delete operations. Dies bedeutet jedoch nicht, dass das Datenbankobjekt tatsächlich eine Daten Bank Sicht sein muss.However, this does not mean that the database object is actually required to be a database view. Alternativ kann es sich um eine Datenbanktabelle handeln, die als schreibgeschützt behandelt wird.It can alternatively be a database table that will be treated as read-only. Im Gegensatz dazu geht EF Core bei regulären Entitäts Typen davon aus, dass ein in der-Methode angegebenes Datenbankobjekt ToTable als Tabelle behandelt werden kann. Dies bedeutet, dass es als Abfrage Quelle, aber auch als Ziel für Update-, DELETE-und INSERT-Vorgänge verwendet werden kann.Conversely, for regular entity types, EF Core assumes that a database object specified in the ToTable method can be treated as a table , meaning that it can be used as a query source but also targeted by update, delete and insert operations. In der Tat können Sie den Namen einer Daten Bank Sicht in angeben, ToTable und alles sollte einwandfrei funktionieren, solange die Sicht so konfiguriert ist, dass Sie für die Datenbank aktualisierbar ist.In fact, you can specify the name of a database view in ToTable and everything should work fine as long as the view is configured to be updatable on the database.

Hinweis

ToView geht davon aus, dass das Objekt bereits in der Datenbank vorhanden ist, und wird nicht durch Migrationen erstellt.ToView assumes that the object already exists in the database and it won't be created by migrations.

BeispielExample

Das folgende Beispiel zeigt, wie Sie schlüssellose Entitäts Typen verwenden, um eine Daten Bank Sicht abzufragen.The following example shows how to use keyless entity types to query a database view.

Tipp

Das in diesem Artikel verwendete Beispiel finden Sie auf GitHub.You can view this article's sample on GitHub.

Zunächst definieren wir einen einfachen Blog und ein Post-Modell:First, we define a simple Blog and Post model:

public class Blog
{
    public int BlogId { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
    public ICollection<Post> Posts { get; set; }
}

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

Als nächstes definieren wir eine einfache Daten Bank Ansicht, die es uns ermöglicht, die Anzahl von Beiträgen abzufragen, die mit den einzelnen Blogs verknüpft sind:Next, we define a simple database view that will allow us to query the number of posts associated with each blog:

db.Database.ExecuteSqlRaw(
    @"CREATE VIEW View_BlogPostCounts AS 
        SELECT b.Name, Count(p.PostId) as PostCount 
        FROM Blogs b
        JOIN Posts p on p.BlogId = b.BlogId
        GROUP BY b.Name");

Als nächstes definieren wir eine Klasse, die das Ergebnis aus der Daten Bank Sicht enthält:Next, we define a class to hold the result from the database view:

public class BlogPostsCount
{
    public string BlogName { get; set; }
    public int PostCount { get; set; }
}

Als Nächstes konfigurieren wir den Entitätstyp "Schlüssel" in " onmodelcreating " mithilfe der HasNoKey API.Next, we configure the keyless entity type in OnModelCreating using the HasNoKey API. Wir verwenden die fließende Konfigurations-API, um die Zuordnung für den Entitätstyp "Schlüssel" zu konfigurieren:We use fluent configuration API to configure the mapping for the keyless entity type:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<BlogPostsCount>(eb =>
        {
            eb.HasNoKey();
            eb.ToView("View_BlogPostCounts");
            eb.Property(v => v.BlogName).HasColumnName("Name");
        });
}

Als Nächstes konfigurieren wir den so, dass er DbContext Folgendes einschließt DbSet<T> :Next, we configure the DbContext to include the DbSet<T>:

public DbSet<BlogPostsCount> BlogPostCounts { get; set; }

Schließlich können wir die Daten Bank Sicht standardmäßig Abfragen:Finally, we can query the database view in the standard way:

var postCounts = db.BlogPostCounts.ToList();

foreach (var postCount in postCounts)
{
    Console.WriteLine($"{postCount.BlogName} has {postCount.PostCount} posts.");
    Console.WriteLine();
}

Tipp

Beachten Sie, dass wir auch eine Kontext Stufen-Abfrage Eigenschaft (dbset) definiert haben, die als Stamm für Abfragen dieses Typs fungiert.Note we have also defined a context level query property (DbSet) to act as a root for queries against this type.

Tipp

Um Schlüssel-Entitäts Typen, die Ansichten zugeordnet sind, mithilfe des Speicher internen Anbieters zu testen, ordnen Sie Sie einer Abfrage über zu ToInMemoryQuery .To test keyless entity types mapped to views using the in-memory provider map them to a query via ToInMemoryQuery. Weitere Informationen finden Sie unter ausführbares Beispiel mit dieser Technik.See a runnable sample using this technique for more details.