AbfragetypenQuery Types

Hinweis

Dieses Feature ist neu in EF Core 2.1This feature is new in EF Core 2.1

Zusätzlich zu den Entitätstypen, kann ein EF Core-Modell enthalten Abfragetypen, die zum Datenbankabfragen für Daten ausführen, auf denen die Entitätstypen zugeordnet wird nicht verwendet werden können.In addition to entity types, an EF Core model can contain query types, which can be used to carry out database queries against data that isn't mapped to entity types.

Vergleichen von Abfragetypen, die EntitätstypenCompare query types to entity types

Abfragetypen sind wie Entitätstypen in, das sie:Query types are like entity types in that they:

  • Können mit dem Modell hinzugefügt werden, entweder in OnModelCreating oder über eine "set"-Eigenschaft in einer abgeleiteten "DbContext".Can be added to the model either in OnModelCreating or via a "set" property on a derived DbContext.
  • Unterstützt viele der gleichen Zuordnungsfunktionen, wie die Vererbungseigenschaften Zuordnung und die Navigation.Support many of the same mapping capabilities, like inheritance mapping and navigation properties. Für relationale Speicher können sie die Ziel-Datenbank-Objekte und Spalten über die Methoden der fluent-API oder datenanmerkungen 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 Entität Typen in, das sie:However, they are different from entity types in that they:

  • Erfordern Sie keinen Schlüssel definiert werden.Do not require a key to be defined.
  • Werden nie damit Änderungen nachverfolgt, auf die "DbContext" und daher nie eingefügt, aktualisiert oder gelöscht werden in der Datenbank.Are never tracked for changes on the DbContext and therefore are never inserted, updated or deleted on the database.
  • Gemäß der Konvention werden nicht ermittelt werden.Are never discovered by convention.
  • Unterstützen Sie nur eine Teilmenge der Funktionen für die Zuordnung von Navigation - insbesondere:Only support a subset of navigation mapping capabilities - Specifically:
    • Sie können nicht als das prinzipalende der Beziehung fungieren.They may never act as the principal end of a relationship.
    • Sie können nur auf Entitäten verweisen verweisnavigationseigenschaften enthalten.They can only contain reference navigation properties pointing to entities.
    • Entitäten können keine Navigationseigenschaften für Abfragetypen enthalten.Entities cannot contain navigation properties to query types.
  • Adressiert werden, auf die ModelBuilder mithilfe der Query Methode anstelle der Entity Methode.Are addressed on the ModelBuilder using the Query method rather than the Entity method.
  • Zugeordnet sind, auf die "DbContext" über Eigenschaften vom Typ DbQuery<T> statt DbSet<T>Are mapped on the DbContext through properties of type DbQuery<T> rather than DbSet<T>
  • Datenbankobjekte mit zugeordnet sind die ToView Methode statt ToTable.Are mapped to database objects using the ToView method, rather than ToTable.
  • Zugeordnet werden kann eine Abfrage definiert : Definieren der Abfrage ist eine sekundäre Abfrage, die im Modell, die eine Datenquelle für den Abfragetyp dient deklariert.May be mapped to a defining query - A defining query is a secondary query declared in the model that acts a data source for a query type.

VerwendungsszenarienUsage scenarios

Einige der wichtigsten Verwendungsszenarien für Abfragetypen sind:Some of the main usage scenarios for query types are:

  • Dient als Rückgabetyp für ad-hoc- FromSql() Abfragen.Serving as the return type for ad hoc FromSql() queries.
  • Zuordnung zu Datenbankansichten.Mapping to database views.
  • Zuordnung zu Tabellen, die nicht über einen definierten Primärschlüssel verfügen.Mapping to tables that do not have a primary key defined.
  • Zuordnen zu Abfragen, die im Modell definiert.Mapping to queries defined in the model.

Zuordnen von DatenbankobjektenMapping to database objects

Zuordnen der Abfragetyp auf ein Datenbankobjekt wird erreicht, indem die ToView fluent-API.Mapping a query type to a database object is achieved using the ToView fluent API. Aus der Perspektive von EF Core, das Datenbankobjekt, das in dieser Methode wird ein Ansicht, was bedeutet, dass es als eine nur-Lese Query-Datenquelle behandelt wird kann nicht Ziel von Updates, insert oder delete-Operationen.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 erforderlich ist ist, eine Datenbanksicht sein - es kann auch eine Datenbanktabelle, die als schreibgeschützt behandelt werden.However, this does not mean that the database object is actually required to be a database view - It can alternatively be a database table that will be treated as read-only. Im Gegensatz dazu für Entitätstypen, EF Core geht davon aus, dass ein Datenbankobjekt in angegeben die ToTable Methode behandelt werden kann, als eine Tabelle, was bedeutet, dass er kann als ein Query-Datenquelle verwendet werden, sondern auch das Ziel aktualisieren, löschen und einfügen Vorgänge.Conversely, for 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 angeben, den Namen einer Datenbanksicht in ToTable und alles sollte gut funktionieren, solange die Ansicht für die für die Datenbank aktualisierbar sein, konfiguriert 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.

BeispielExample

Das folgende Beispiel zeigt, wie Sie den Abfragetyp zu verwenden, um eine Datenbankansicht abzufragen.The following example shows how to use Query Type 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.

Zuerst definieren wir ein einfaches Blog und 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 Datenbank-Ansicht, die wir Abfragen die Anzahl an Beiträgen, die jeden Blog zugeordnet werden kann:Next, we define a simple database view that will allow us to query the number of posts associated with each blog:

db.Database.ExecuteSqlCommand(
    @"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, um das Ergebnis aus der Datenbankansicht enthalten soll: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 Abfragetyp in "onmodelcreating" mithilfe der modelBuilder.Query<T> API.Next, we configure the query type in OnModelCreating using the modelBuilder.Query<T> API. Verwenden wir standard fluent-Konfigurations-APIs, um die Zuordnung für den Abfragetyp zu konfigurieren:We use standard fluent configuration APIs to configure the mapping for the Query Type:

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

Schließlich können wir die Datenbanksicht auf die übliche Weise 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 Ebene Abfrageeigenschaft (DbQuery) fungieren als Stamm für Abfragen gegen diese Art von Kontext definiert haben.Note we have also defined a context level query property (DbQuery) to act as a root for queries against this type.