Types de requêtesQuery Types

Note

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

En plus des types d’entité, un modèle EF Core peut contenir types de requête, qui peut être utilisé pour effectuer des requêtes de base de données sur des données qui n’est pas mappées aux types d’entité.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.

Comparer des types de requête aux types d’entitéCompare query types to entity types

Types de requêtes sont comme les types d’entités qui elles :Query types are like entity types in that they:

  • Peuvent être ajoutées au modèle, soit dans OnModelCreating ou via une propriété « set » sur une dérivée DbContext.Can be added to the model either in OnModelCreating or via a "set" property on a derived DbContext.
  • Prend en charge la plupart des mêmes fonctionnalités de mappage, comme les propriétés de navigation et de mappage de l’héritage.Support many of the same mapping capabilities, like inheritance mapping and navigation properties. Sur des magasins relationnels, ils peuvent configurer les objets de base de données cible et les colonnes par le biais de méthodes de l’API fluent ou des annotations de données.On relational stores, they can configure the target database objects and columns via fluent API methods or data annotations.

Toutefois, ils sont différents à partir de l’entité types dans ce qu’il :However, they are different from entity types in that they:

  • Ne nécessitent pas une clé à définir.Do not require a key to be defined.
  • Ne sont jamais suivis pour les modifications sur le DbContext et par conséquent sont jamais insérées, mises à jour ou supprimées sur la base de données.Are never tracked for changes on the DbContext and therefore are never inserted, updated or deleted on the database.
  • Ne sont jamais découverts par convention.Are never discovered by convention.
  • Prennent uniquement en charge un sous-ensemble des fonctionnalités de mappage de navigation - en particulier :Only support a subset of navigation mapping capabilities - Specifically:
    • Ils ne peuvent jamais agir en tant que la terminaison principale d’une relation.They may never act as the principal end of a relationship.
    • Ils peuvent contenir uniquement des propriétés de navigation de référence qui pointe vers des entités.They can only contain reference navigation properties pointing to entities.
    • Entités ne peut pas contenir les propriétés de navigation aux types de requêtes.Entities cannot contain navigation properties to query types.
  • Sont traitées sur le ModelBuilder à l’aide de la Query méthode plutôt que la Entity (méthode).Are addressed on the ModelBuilder using the Query method rather than the Entity method.
  • Sont mappées sur le DbContext via les propriétés de type DbQuery<T> au lieu de DbSet<T>Are mapped on the DbContext through properties of type DbQuery<T> rather than DbSet<T>
  • Sont mappées aux objets de base de données en utilisant le ToView (méthode), plutôt que ToTable.Are mapped to database objects using the ToView method, rather than ToTable.
  • Peut être mappé à un définition de requête : une définition de requête est une requête secondaire déclarée dans le modèle qui fait Office de source de données pour un type de requête.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.

Scénarios d'utilisationUsage scenarios

Les principaux scénarios d’utilisation pour les types de requêtes sont notamment :Some of the main usage scenarios for query types are:

  • Agissant comme le type de retour pour ad hoc FromSql() requêtes.Serving as the return type for ad hoc FromSql() queries.
  • Mappage avec les vues de base de données.Mapping to database views.
  • Mappage de tables qui n’ont pas d’une clé primaire définie.Mapping to tables that do not have a primary key defined.
  • Mappage à des requêtes définies dans le modèle.Mapping to queries defined in the model.

Mappage aux objets de base de donnéesMapping to database objects

Mappage d’un type de requête à un objet de base de données est obtenue à l’aide de la ToView API fluent.Mapping a query type to a database object is achieved using the ToView fluent API. Du point de vue d’EF Core, l’objet de base de données spécifié dans cette méthode est un vue, ce qui signifie qu’il est traité comme une source de la requête en lecture seule et ne peut pas être la cible de mise à jour, insérer ou supprimer des opérations.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. Toutefois, cela ne signifie pas que l’objet de base de données soit réellement nécessaire pour être une vue de base de données, il peut également être une table de base de données qui est traitée comme étant en lecture seule.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. À l’inverse, pour les types d’entité, EF Core suppose qu’un objet de base de données spécifiée dans le ToTable méthode peut être traitée comme un table, ce qui signifie qu’il peut être utilisé en tant que requête source, mais également ciblé par la mise à jour, supprimer et insérer opérations.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. En fait, vous pouvez spécifier le nom d’une vue de base de données dans ToTable et tout devrait fonctionner correctement tant que la vue est configurée pour être mis à jour sur la base de données.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.

ExempleExample

L’exemple suivant montre comment utiliser le Type de requête pour interroger une vue de base de données.The following example shows how to use Query Type to query a database view.

Conseil

Vous pouvez afficher cet exemple sur GitHub.You can view this article's sample on GitHub.

Tout d’abord, nous définissons un modèle simple de Blog et Post :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; }
}

Ensuite, nous définissons une vue de base de données simple qui nous permettra d’interroger le nombre de messages associée à chaque blog :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 Name, Count(p.PostId) as PostCount from Blogs b
        JOIN Posts p on p.BlogId = b.BlogId
        GROUP BY b.Name");

Ensuite, nous définissons une classe pour contenir le résultat de la vue de base de données :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; }
}

Ensuite, nous configurer le type de requête dans OnModelCreating à l’aide de la modelBuilder.Query<T> API.Next, we configure the query type in OnModelCreating using the modelBuilder.Query<T> API. Nous utilisons des API de configuration fluent standard pour configurer le mappage pour le Type de requête :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");
}

Enfin, nous pouvons interroger la vue de base de données de manière standard :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();
}

Conseil

Notez que nous avons également défini une propriété de niveau requête (DbQuery) d’agir en tant que racine pour les requêtes sur ce type de contexte.Note we have also defined a context level query property (DbQuery) to act as a root for queries against this type.