-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add documentation for pre-convention model configuration
Fixes #3278
- Loading branch information
1 parent
cef190d
commit b84b75b
Showing
4 changed files
with
78 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
--- | ||
title: Model Bulk Configuration - EF Core | ||
description: How to apply bulk configuration during model building in Entity Framework Core | ||
author: AndriySvyryd | ||
ms.date: 10/25/2021 | ||
uid: core/modeling/bulk-configuration | ||
--- | ||
# Model bulk configuration | ||
|
||
When an aspect needs to be configured in the same way across multiple entity types the following techniques allow to reduce code duplication and consolidate the logic. | ||
|
||
## Foreign key shadow properties | ||
|
||
Shadow properties are most often used for foreign key properties, where the relationship between two entities is represented by a foreign key value in the database, but the relationship is managed on the entity types using navigation properties between the entity types. By convention, EF will introduce a shadow property when a relationship is discovered but no foreign key property is found in the dependent entity class. | ||
|
||
The property will be named `<navigation property name><principal key property name>` (the navigation on the dependent entity, which points to the principal entity, is used for the naming). If the principal key property name includes the name of the navigation property, then the name will just be `<principal key property name>`. If there is no navigation property on the dependent entity, then the principal type name is used in its place. | ||
|
||
For example, the following code listing will result in a `BlogId` shadow property being introduced to the `Post` entity: | ||
|
||
[!code-csharp[Main](../../../samples/core/Modeling/ShadowAndIndexerProperties/ShadowForeignKey.cs?name=Conventions&highlight=21-23)] | ||
|
||
## Configuring shadow properties | ||
|
||
You can use the Fluent API to configure shadow properties. Once you have called the string overload of `Property`, you can chain any of the configuration calls you would for other properties. In the following sample, since `Blog` has no CLR property named `LastUpdated`, a shadow property is created: | ||
|
||
[!code-csharp[Main](../../../samples/core/Modeling/ShadowAndIndexerProperties/ShadowProperty.cs?name=ShadowProperty&highlight=8)] | ||
|
||
If the name supplied to the `Property` method matches the name of an existing property (a shadow property or one defined on the entity class), then the code will configure that existing property rather than introducing a new shadow property. | ||
|
||
## Accessing shadow properties | ||
|
||
Shadow property values can be obtained and changed through the `ChangeTracker` API: | ||
|
||
```csharp | ||
context.Entry(myBlog).Property("LastUpdated").CurrentValue = DateTime.Now; | ||
``` | ||
|
||
Shadow properties can be referenced in LINQ queries via the `EF.Property` static method: | ||
|
||
```csharp | ||
var blogs = context.Blogs | ||
.OrderBy(b => EF.Property<DateTime>(b, "LastUpdated")); | ||
``` | ||
|
||
Shadow properties cannot be accessed after a no-tracking query since the entities returned are not tracked by the change tracker. | ||
|
||
## Configuring indexer properties | ||
|
||
You can use the Fluent API to configure indexer properties. Once you've called the method `IndexerProperty`, you can chain any of the configuration calls you would for other properties. In the following sample, `Blog` has an indexer defined and it will be used to create an indexer property. | ||
|
||
[!code-csharp[Main](../../../samples/core/Modeling/ShadowAndIndexerProperties/IndexerProperty.cs?name=IndexerProperty&highlight=7)] | ||
|
||
If the name supplied to the `IndexerProperty` method matches the name of an existing indexer property, then the code will configure that existing property. If the entity type has a property, which is backed by a property on the entity class, then an exception is thrown since indexer properties must only be accessed via the indexer. | ||
|
||
Indexer properties can be referenced in LINQ queries via the `EF.Property` static method as shown above or by using the CLR indexer property. | ||
|
||
## Property bag entity types | ||
|
||
> [!NOTE] | ||
> Support for Property bag entity types was introduced in EF Core 5.0. | ||
Entity types that contain only indexer properties are known as property bag entity types. These entity types don't have shadow properties, and EF creates indexer properties instead. Currently only `Dictionary<string, object>` is supported as a property bag entity type. It must be configured as a [shared-type entity type](entity-types.md#shared-type-entity-types) with a unique name and the corresponding `DbSet` property must be implemented using a `Set` call. | ||
|
||
[!code-csharp[Main](../../../samples/core/Modeling/ShadowAndIndexerProperties/SharedType.cs?name=SharedType&highlight=3,7)] | ||
|
||
Property bag entity types can be used wherever a normal entity type is used, including as an owned entity type. However, they do have certain limitations: | ||
|
||
- They can't have shadow properties. | ||
- [Indexer navigations aren't supported](https://github.com/dotnet/efcore/issues/13729) | ||
- [Inheritance isn't supported](https://github.com/dotnet/efcore/issues/9630) | ||
- [Some relationship model-building API lack overloads for shared-type entity types](https://github.com/dotnet/efcore/issues/23255) | ||
- [Other types can't be marked as property bags](https://github.com/dotnet/efcore/issues/22009) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters