Skip to content

Commit

Permalink
Update keyless entity types topic
Browse files Browse the repository at this point in the history
Fixes #1314
  • Loading branch information
AndriySvyryd committed Sep 13, 2019
1 parent 51b8819 commit 93eba2c
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 35 deletions.
54 changes: 25 additions & 29 deletions entity-framework/core/modeling/query-types.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,49 @@
---
title: Query Types - EF Core
author: anpete
title: Keyless Entity Types - EF Core
author: AndriySvyryd
ms.author: ansvyryd
ms.date: 02/26/2018
ms.assetid: 9F4450C5-1A3F-4BB6-AC19-9FAC64292AAD
uid: core/modeling/query-types
---
# Query Types
# Keyless Entity Types
> [!NOTE]
> This feature is new in EF Core 2.1
> This feature is new in EF Core 2.1. Prior to 3.0 they were known as Query Types
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.
In addition to normal 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.

## Compare query types to entity types
## Keyless Entity Types Characteristics

Query types are like entity types in that they:
Keyless entity types support many of the same mapping capabilities, like inheritance mapping and navigation properties. On relational stores, they can configure the target database objects and columns via fluent API methods or data annotations.

- Can be added to the model either in `OnModelCreating` or via a "set" property on a derived _DbContext_.
- Support many of the same mapping capabilities, like inheritance mapping and navigation properties. On relational stores, they can configure the target database objects and columns via fluent API methods or data annotations.
However, they are different from normal entity types in that they:

However, they are different from entity types in that they:

- Do not require a key to be defined.
- Are never tracked for changes on the _DbContext_ and therefore are never inserted, updated or deleted on the database.
- Cannot have a key defined.
- Are never tracked for changes in the _DbContext_ and therefore are never inserted, updated or deleted on the database.
- Are never discovered by convention.
- Only support a subset of navigation mapping capabilities - Specifically:
- Only support a subset of navigation mapping capabilities, specifically:
- They may never act as the principal end of a relationship.
- They can only contain reference navigation properties pointing to entities.
- Entities cannot contain navigation properties to query types.
- Are addressed on the _ModelBuilder_ using the `Query` method rather than the `Entity` method.
- Are mapped on the _DbContext_ through properties of type `DbQuery<T>` rather than `DbSet<T>`
- Are mapped to database objects using the `ToView` method, rather than `ToTable`.
- 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.
- Entities cannot contain navigation properties to keyless entity types.
- Need to be configured with `.HasNoKey()` method call.
- May be mapped to a _defining query_. A defining query is a query declared in the model that acts as a data source for a keyless entity type.

## Usage scenarios

Some of the main usage scenarios for query types are:
Some of the main usage scenarios for keyless entity types are:

- Serving as the return type for ad hoc `FromSql()` queries.
- Mapping to database views.
- Serving as the return type for `FromSql()` queries.
- Mapping to database views that do not contain a primary key.
- Mapping to tables that do not have a primary key defined.
- Mapping to queries defined in the model.

## Mapping to database objects

Mapping a query type to a database object is achieved using the `ToView` fluent API. 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. 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. 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 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.
Mapping a keyless entity type to a database object is achieved using the `ToTable` or `ToView` fluent API. 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. 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. Conversely, for normal 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 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.

## Example

The following example shows how to use Query Type to query a database view.
The following example shows how to use keyless entity type to query a database view.

> [!TIP]
> You can view this article's [sample](https://github.com/aspnet/EntityFramework.Docs/tree/master/samples/core/QueryTypes) on GitHub.
Expand All @@ -64,18 +60,18 @@ Next, we define a class to hold the result from the database view:

[!code-csharp[Main](../../../samples/core/QueryTypes/Program.cs#QueryType)]

Next, we configure the query type in _OnModelCreating_ using the `modelBuilder.Query<T>` API.
We use standard fluent configuration APIs to configure the mapping for the Query Type:
Next, we configure the keyless entity type in _OnModelCreating_ using the `HasNoKey` API.
We use standard fluent configuration API to configure the mapping for the keyless entity type:

[!code-csharp[Main](../../../samples/core/QueryTypes/Program.cs#Configuration)]

Next, we configure the `DbContext` to include the `DbQuery<T>`:
Next, we configure the `DbContext` to include the `DbSet<T>`:

[!code-csharp[Main](../../../samples/core/QueryTypes/Program.cs#DbQuery)]
[!code-csharp[Main](../../../samples/core/QueryTypes/Program.cs#DbSet)]

Finally, we can query the database view in the standard way:

[!code-csharp[Main](../../../samples/core/QueryTypes/Program.cs#Query)]

> [!TIP]
> Note we have also defined a context level query property (DbQuery) to act as a root for queries against this type.
> Note we have also defined a context level query property (DbSet) to act as a root for queries against this type.
6 changes: 3 additions & 3 deletions samples/core/QueryTypes/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,13 @@ FROM Blogs b
public class BloggingContext : DbContext
{
private static readonly ILoggerFactory _loggerFactory
= new LoggerFactory().AddConsole((s, l) => l == LogLevel.Information && !s.EndsWith("Connection"));
= LoggerFactory.Create(builder => builder.AddConsole().AddFilter((c, l) => l == LogLevel.Information && !c.EndsWith("Connection")));

public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }

#region DbQuery
public DbQuery<BlogPostsCount> BlogPostCounts { get; set; }
#region DbSet
public DbSet<BlogPostsCount> BlogPostCounts { get; set; }
#endregion

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
Expand Down
6 changes: 3 additions & 3 deletions samples/core/QueryTypes/QueryTypes.csproj
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<RootNamespace>Samples</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.0-*" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.0-*" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0-preview9.19423.6" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.0.0-preview9.19423.4" />
</ItemGroup>
</Project>

0 comments on commit 93eba2c

Please sign in to comment.