diff --git a/entity-framework/core/change-tracking/change-detection.md b/entity-framework/core/change-tracking/change-detection.md index 6f9e64f679..7404a6e28a 100644 --- a/entity-framework/core/change-tracking/change-detection.md +++ b/entity-framework/core/change-tracking/change-detection.md @@ -8,7 +8,7 @@ uid: core/change-tracking/change-detection # Change Detection and Notifications -Each instance tracks changes made to entities. These tracked entities in turn drive the changes to the database when is called. This is covered in [Change Tracking in EF Core](xref:core/change-tracking/index), and this document assumes that entity states and the basics of Entity Framework Core (EF Core) change tracking are understood. +Each instance tracks changes made to entities. These tracked entities in turn drive the changes to the database when is called. This is covered in [Change Tracking in EF Core](xref:core/change-tracking/index), and this document assumes that entity states and the basics of Entity Framework Core (EF Core) change tracking are understood. Tracking property and relationship changes requires that the DbContext is able to detect these changes. This document covers how this detection happens, as well as how to use property notifications or change-tracking proxies to force immediate detection of changes. @@ -121,7 +121,7 @@ Contrast this to the following code which modifies the entities in the same way, --> [!code-csharp[Snapshot_change_tracking_2](../../../samples/core/ChangeTracking/ChangeDetectionAndNotifications/SnapshotSamples.cs?name=Snapshot_change_tracking_2)] -In this case the change tracker debug view shows that all entity states and property modifications are known, even though detection of changes has not happened. This is because is an EF Core method, which means that EF Core immediately knows about the change made by this method. Likewise, calling allows EF Core to immediately know about the new entity and track it appropriately. +In this case the change tracker debug view shows that all entity states and property modifications are known, even though detection of changes has not happened. This is because is an EF Core method, which means that EF Core immediately knows about the change made by this method. Likewise, calling allows EF Core to immediately know about the new entity and track it appropriately. > [!TIP] > Don't attempt to avoid detecting changes by always using EF Core methods to make entity changes. Doing so is often more cumbersome and performs less well than making changes to entities in the normal way. The intention of this document is to inform as to when detecting changes is needed and when it is not. The intention is not to encourage avoidance of change detection. @@ -130,15 +130,15 @@ In this case the change tracker debug view shows that all entity states and prop is called automatically by methods where doing so is likely to impact the results. These methods are: -- and , to ensure that all changes are detected before updating the database. -- and , to ensure entity states and modified properties are up-to-date. +- and , to ensure that all changes are detected before updating the database. +- and , to ensure entity states and modified properties are up-to-date. - , to ensure that the result is accurate. - , to ensure correct entity states for principal/parent entities before cascading. -- , to ensure that the tracked graph is up-to-date. +- , to ensure that the tracked graph is up-to-date. There are also some places where detection of changes happens on only a single entity instance, rather than on the entire graph of tracked entities. These places are: -- When using , to ensure that the entity's state and modified properties are up-to-date. +- When using , to ensure that the entity's state and modified properties are up-to-date. - When using methods such as `Property`, `Collection`, `Reference` or `Member` to ensure property modifications, current values, etc. are up-to-date. - When a dependent/child entity is going to be deleted because a required relationship has been severed. This detects when an entity should not be deleted because it has been re-parented. @@ -176,7 +176,7 @@ The performance of detecting changes is not a bottleneck for most applications. --> [!code-csharp[SaveChanges](../../../samples/core/ChangeTracking/ChangeDetectionAndNotifications/SnapshotSamples.cs?name=SaveChanges)] -As we know from the previous section, both and automatically detect changes. However, after calling Entries, the code does not then make any entity or property state changes. (Setting normal property values on Added entities does not cause any state changes.) The code therefore disables unnecessary automatic change detection when calling down into the base SaveChanges method. The code also makes use of a try/finally block to ensure that the default setting is restored even if SaveChanges fails. +As we know from the previous section, both and automatically detect changes. However, after calling Entries, the code does not then make any entity or property state changes. (Setting normal property values on Added entities does not cause any state changes.) The code therefore disables unnecessary automatic change detection when calling down into the base SaveChanges method. The code also makes use of a try/finally block to ensure that the default setting is restored even if SaveChanges fails. > [!TIP] > Do not assume that your code must disable automatic change detection to perform well. This is only needed when profiling an application tracking many entities indicates that performance of change detection is an issue. @@ -234,7 +234,7 @@ Notification entities make use of the [!code-csharp[Model](../../../samples/core/ChangeTracking/ChangeDetectionAndNotifications/NotificationEntitiesSamples.cs?name=Model)] -In addition, any collection navigations must implement `INotifyCollectionChanged`; in the example above this is satisfied by using an of posts. EF Core also ships with an implementation that has more efficient lookups at the expense of stable ordering. +In addition, any collection navigations must implement `INotifyCollectionChanged`; in the example above this is satisfied by using an of posts. EF Core also ships with an implementation that has more efficient lookups at the expense of stable ordering. Most of this notification code is typically moved into an unmapped base class. For example: @@ -283,7 +283,7 @@ Most of this notification code is typically moved into an unmapped base class. F There is no way for EF Core to validate that `INotifyPropertyChanging` or `INotifyPropertyChanged` are fully implemented for use with EF Core. In particular, some uses of these interfaces do so with notifications only on certain properties, rather than on all properties (including navigations) as required by EF Core. For this reason, EF Core does not automatically hook into these events. -Instead, EF Core must be configured to use these notification entities. This is usually done for all entity types by calling . For example: +Instead, EF Core must be configured to use these notification entities. This is usually done for all entity types by calling . For example: [!code-csharp[OnModelCreating](../../../samples/core/ChangeTracking/ChangeDetectionAndNotifications/NotificationWithBaseSamples.cs?name=OnModelCreating)] -(The strategy can also be set differently for different entity types using , but this is usually counterproductive since DetectChanges is still required for those types that are not notification entities.) +(The strategy can also be set differently for different entity types using , but this is usually counterproductive since DetectChanges is still required for those types that are not notification entities.) Full notification change tracking requires that both `INotifyPropertyChanging` and `INotifyPropertyChanged` are implemented. This allows original values to be saved just before the property value is changed, avoiding the need for EF Core to create a snapshot when tracking the entity. Entity types that implement only `INotifyPropertyChanged` can also be used with EF Core. In this case, EF still creates a snapshot when tracking an entity to keep track of original values, but then uses the notifications to detect changes immediately, rather than needing DetectChanges to be called. @@ -357,7 +357,7 @@ Post {Id: 2} Unchanged ## Change-tracking proxies -EF Core can dynamically generate proxy types that implement and . This requires installing the [Microsoft.EntityFrameworkCore.Proxies](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Proxies/) NuGet package, and enabling change-tracking proxies with For example: +EF Core can dynamically generate proxy types that implement and . This requires installing the [Microsoft.EntityFrameworkCore.Proxies](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Proxies/) NuGet package, and enabling change-tracking proxies with For example: [!code-csharp[Work_with_a_single_property_1b](../../../samples/core/ChangeTracking/AccessingTrackedEntities/Samples.cs?name=Work_with_a_single_property_1b)] -The returned can then be used to access information about the property. For example, it can be used to get and set the current value of the property on this entity: +The returned can then be used to access information about the property. For example, it can be used to get and set the current value of the property on this entity: [!code-csharp[Work_with_a_single_property_1d](../../../samples/core/ChangeTracking/AccessingTrackedEntities/Samples.cs?name=Work_with_a_single_property_1d)] -Both of the Property methods used above return a strongly-typed generic instance. Using this generic type is preferred because it allows access to property values without [boxing value types](/dotnet/csharp/programming-guide/types/boxing-and-unboxing). However, if the type of entity or property is not known at compile-time, then a non-generic can be obtained instead: +Both of the Property methods used above return a strongly-typed generic instance. Using this generic type is preferred because it allows access to property values without [boxing value types](/dotnet/csharp/programming-guide/types/boxing-and-unboxing). However, if the type of entity or property is not known at compile-time, then a non-generic can be obtained instead: [!code-csharp[Work_with_a_single_navigation_1](../../../samples/core/ChangeTracking/AccessingTrackedEntities/Samples.cs?name=Work_with_a_single_navigation_1)] -Navigations can also be collections of related entities when used for the "many" sides of one-to-many and many-to-many relationships. The methods are used to access collection navigations. For example: +Navigations can also be collections of related entities when used for the "many" sides of one-to-many and many-to-many relationships. The methods are used to access collection navigations. For example: [!code-csharp[Work_with_a_single_navigation_2a](../../../samples/core/ChangeTracking/AccessingTrackedEntities/Samples.cs?name=Work_with_a_single_navigation_2a)] -Some operations are common for all navigations. These can be accessed for both reference and collection navigations using the method. Note that only non-generic access is available when accessing all navigations together. For example: +Some operations are common for all navigations. These can be accessed for both reference and collection navigations using the method. Note that only non-generic access is available when accessing all navigations together. For example: [!code-csharp[Work_with_a_single_navigation_2b](../../../samples/core/ChangeTracking/AccessingTrackedEntities/Samples.cs?name=Work_with_a_single_navigation_2b)] -The following table summarizes ways to use , , and : +The following table summarizes ways to use , , and : | NavigationEntry member | Description |:----------------------------------------------------------------------------------------------------------|---------------------- @@ -185,7 +185,7 @@ The following table summarizes ways to use returns an of for every property of the entity. This can be used to perform an action for every property of the entity. For example, to set any DateTime property to `DateTime.Now`: + returns an of for every property of the entity. This can be used to perform an action for every property of the entity. For example, to set any DateTime property to `DateTime.Now`: [!code-csharp[BlogDto](../../../samples/core/ChangeTracking/AccessingTrackedEntities/Samples.cs?name=BlogDto)] -This can be used to set the current values of a tracked entity using : +This can be used to set the current values of a tracked entity using : [!code-csharp[OrderLine](../../../samples/core/ChangeTracking/AccessingTrackedEntities/Samples.cs?name=OrderLine)] -The composite key must be configured in to define the key parts _and their order_. For example: +The composite key must be configured in to define the key parts _and their order_. For example: [!code-csharp[Using_DbSet_Local_to_query_tracked_entities_1](../../../samples/core/ChangeTracking/AccessingTrackedEntities/Samples.cs?name=Using_DbSet_Local_to_query_tracked_entities_1)] -Notice that, unlike , `DbSet.Local` returns entity instances directly. An EntityEntry can, of course, always be obtained for the returned entity by calling . +Notice that, unlike , `DbSet.Local` returns entity instances directly. An EntityEntry can, of course, always be obtained for the returned entity by calling . ### The local view - returns a view of locally tracked entities that reflects the current of those entities. Specifically, this means that: + returns a view of locally tracked entities that reflects the current of those entities. Specifically, this means that: - `Added` entities are included. Note that this is not the case for normal EF Core queries, since `Added` entities do not yet exist in the database and so are therefore never returned by a database query. - `Deleted` entities are excluded. Note that this is again not the case for normal EF Core queries, since `Deleted` entities still exist in the database and so _are_ returned by database queries. @@ -534,7 +534,7 @@ Notice that the deleted post is removed from the local view, and the added post ### Using Local to add and remove entities - returns an instance of . This is an implementation of that generates and responds to notifications when entities are added and removed from the collection. (This is the same concept as , but implemented as a projection over existing EF Core change tracking entries, rather than as an independent collection.) + returns an instance of . This is an implementation of that generates and responds to notifications when entities are added and removed from the collection. (This is the same concept as , but implemented as a projection over existing EF Core change tracking entries, rather than as an independent collection.) The local view's notifications are hooked into DbContext change tracking such that the local view stays in sync with the DbContext. Specifically: @@ -579,10 +579,10 @@ The output remains unchanged from the previous example because changes made to t ### Using the local view for Windows Forms or WPF data binding - forms the basis for data binding to EF Core entities. However, both Windows Forms and WPF work best when used with the specific type of notifying collection that they expect. The local view supports creating these specific collection types: + forms the basis for data binding to EF Core entities. However, both Windows Forms and WPF work best when used with the specific type of notifying collection that they expect. The local view supports creating these specific collection types: -- returns an for WPF data binding. -- returns a for Windows Forms data binding. +- returns an for WPF data binding. +- returns a for Windows Forms data binding. For example: diff --git a/entity-framework/core/change-tracking/explicit-tracking.md b/entity-framework/core/change-tracking/explicit-tracking.md index 2a8d862d0d..f6786cf9c7 100644 --- a/entity-framework/core/change-tracking/explicit-tracking.md +++ b/entity-framework/core/change-tracking/explicit-tracking.md @@ -8,9 +8,9 @@ uid: core/change-tracking/explicit-tracking # Explicitly Tracking Entities -Each instance tracks changes made to entities. These tracked entities in turn drive the changes to the database when is called. +Each instance tracks changes made to entities. These tracked entities in turn drive the changes to the database when is called. -Entity Framework Core (EF Core) change tracking works best when the same instance is used to both query for entities and update them by calling . This is because EF Core automatically tracks the state of queried entities and then detects any changes made to these entities when SaveChanges is called. This approach is covered in [Change Tracking in EF Core](xref:core/change-tracking/index). +Entity Framework Core (EF Core) change tracking works best when the same instance is used to both query for entities and update them by calling . This is because EF Core automatically tracks the state of queried entities and then detects any changes made to these entities when SaveChanges is called. This approach is covered in [Change Tracking in EF Core](xref:core/change-tracking/index). > [!TIP] > This document assumes that entity states and the basics of EF Core change tracking are understood. See [Change Tracking in EF Core](xref:core/change-tracking/index) for more information on these topics. @@ -19,7 +19,7 @@ Entity Framework Core (EF Core) change tracking works best when the same You can run and debug into all the code in this document by [downloading the sample code from GitHub](https://github.com/dotnet/EntityFramework.Docs/tree/main/samples/core/ChangeTracking/ChangeTrackingInEFCore). > [!TIP] -> For simplicity, this document uses and references synchronous methods such as rather than their async equivalents such as . Calling and awaiting the async method can be substituted unless otherwise noted. +> For simplicity, this document uses and references synchronous methods such as rather than their async equivalents such as . Calling and awaiting the async method can be substituted unless otherwise noted. ## Introduction @@ -28,11 +28,11 @@ Entities can be explicitly "attached" to a methods. +The first of these will be needed by most applications, and is primarily handled by the methods. The second is only needed by applications that change entities or their relationships **_while the entities are not being tracked_**. For example, a web application may send entities to the web client where the user makes changes and sends the entities back. These entities are referred to as "disconnected" since they were originally queried from a DbContext, but were then disconnected from that context when sent to the client. -The web application must now re-attach these entities so that they are again tracked and indicate the changes that have been made such that can make appropriate updates to the database. This is primarily handled by the and methods. +The web application must now re-attach these entities so that they are again tracked and indicate the changes that have been made such that can make appropriate updates to the database. This is primarily handled by the and methods. > [!TIP] > Attaching entities to the _same DbContext instance_ that they were queried from should not normally be needed. Do not routinely perform a no-tracking query and then attach the returned entities to the same context. This will be slower than using a tracking query, and may also result in issues such as missing shadow property values, making it harder to get right. @@ -99,7 +99,7 @@ Notice that the key properties in this model need no additional configuration he ### Explicit key values -An entity must be tracked in the `Added` state to be inserted by . Entities are typically put in the Added state by calling one of , , , , or the equivalent methods on . +An entity must be tracked in the `Added` state to be inserted by . Entities are typically put in the Added state by calling one of , , , , or the equivalent methods on . > [!TIP] > These methods all work in the same way in the context of change tracking. See [Additional Change Tracking Features](xref:core/change-tracking/miscellaneous) for more information. @@ -312,7 +312,7 @@ This is exactly the same end-state as the previous example that used explicit ke ### Explicit key values -Entities returned from queries are tracked in the `Unchanged` state. The `Unchanged` state means that the entity has not been modified since it was queried. A disconnected entity, perhaps returned from a web client in an HTTP request, can be put into this state using either , , or the equivalent methods on . For example, to start tracking an existing blog: +Entities returned from queries are tracked in the `Unchanged` state. The `Unchanged` state means that the entity has not been modified since it was queried. A disconnected entity, perhaps returned from a web client in an HTTP request, can be put into this state using either , , or the equivalent methods on . For example, to start tracking an existing blog: [!code-csharp[DbContext_versus_DbSet_methods_1](../../../samples/core/ChangeTracking/AdditionalChangeTrackingFeatures/Samples.cs?name=DbContext_versus_DbSet_methods_1)] -Notice that is used to create a DbSet for the `PostTag` entity type. This DbSet can then be used to call `Add` with the new join entity instance. +Notice that is used to create a DbSet for the `PostTag` entity type. This DbSet can then be used to call `Add` with the new join entity instance. > [!IMPORTANT] > The CLR type used for join entity types by convention may change in future releases to improve performance. Do not depend on any specific join entity type unless it has been explicitly configured as is done for `Dictionary` in the code above. @@ -97,10 +97,10 @@ Access to entity properties uses the backing field of the property by default. T Sometimes it may be desirable for EF Core to generate side-effects when it modifies property values. For example, when data binding to entities, setting a property may generate notifications to the U.I. which do not happen when setting the field directly. This can be achieved by changing the for: -- All entity types in the model using -- All properties and navigations of a specific entity type using -- A specific property using -- A specific navigation using +- All entity types in the model using +- All properties and navigations of a specific entity type using +- A specific property using +- A specific navigation using Property access modes `Field` and `PreferField` will cause EF Core to access the property value through its backing field. Likewise, `Property` and `PreferProperty` will cause EF Core to access the property value through its getter and setter. @@ -127,7 +127,7 @@ EF Core creates temporary key values when tracking new entities that will have r ### Accessing temporary values -Temporary values are stored in the change tracker and not set onto entity instances directly. However, these temporary values _are_ exposed when using the various mechanisms for [Accessing Tracked Entities](xref:core/change-tracking/entity-entries). For example, the following code accesses a temporary value using : +Temporary values are stored in the change tracker and not set onto entity instances directly. However, these temporary values _are_ exposed when using the various mechanisms for [Accessing Tracked Entities](xref:core/change-tracking/entity-entries). For example, the following code accesses a temporary value using : [!code-csharp[Model](../../../samples/core/ChangeTracking/ChangingFKsAndNavigations/ExplicitJoinEntityWithStringPayloadSamples.cs?name=Model)] -A post can now be tagged in the same way as before, and the join entity will still be created automatically. This entity can then be accessed using one of the mechanisms described in [Accessing Tracked Entities](xref:core/change-tracking/entity-entries). For example, the code below uses to access the join entity instance: +A post can now be tagged in the same way as before, and the join entity will still be created automatically. This entity can then be accessed using one of the mechanisms described in [Accessing Tracked Entities](xref:core/change-tracking/entity-entries). For example, the code below uses to access the join entity instance: [!code-csharp[Many_to_many_relationships_9](../../../samples/core/ChangeTracking/ChangingFKsAndNavigations/ExplicitJoinEntityWithStringPayloadSamples.cs?name=Many_to_many_relationships_9)] -Finally, another way to set payload data is by either overriding or using the event to process entities before updating the database. For example: +Finally, another way to set payload data is by either overriding or using the event to process entities before updating the database. For example: [!code-csharp[RegisterInterceptor](../../../samples/core/Miscellaneous/CommandInterception/Program.cs?name=RegisterInterceptor)] -Alternately, `AddInterceptors` can be called as part of or when creating a instance to pass to the DbContext constructor. +Alternately, `AddInterceptors` can be called as part of or when creating a instance to pass to the DbContext constructor. > [!TIP] > OnConfiguring is still called when AddDbContext is used or a DbContextOptions instance is passed to the DbContext constructor. This makes it the ideal place to apply context configuration regardless of how the DbContext is constructed. @@ -63,7 +63,7 @@ Low-level database interception is split into the three interfaces shown in the The base classes , , and contain no-op implementations for each method in the corresponding interface. Use the base classes to avoid the need to implement unused interception methods. -The methods on each interceptor type come in pairs, with the first being called before the database operation is started, and the second after the operation has completed. For example, is called before a query is executed, and is called after query has been sent to the database. +The methods on each interceptor type come in pairs, with the first being called before the database operation is started, and the second after the operation has completed. For example, is called before a query is executed, and is called after query has been sent to the database. Each pair of methods have both sync and async variations. This allows for asynchronous I/O, such as requesting an access token, to happen as part of intercepting an async database operation. @@ -250,7 +250,7 @@ In the `Executing` method (i.e. before making a database call), the interceptor --> [!code-csharp[ReaderExecutingAsync](../../../samples/core/Miscellaneous/CachingInterception/CachingCommandInterceptor.cs?name=ReaderExecutingAsync)] -Notice how the code calls and passes a replacement containing the cached data. This InterceptionResult is then returned, causing suppression of query execution. The replacement reader is instead used by EF Core as the results of the query. +Notice how the code calls and passes a replacement containing the cached data. This InterceptionResult is then returned, causing suppression of query execution. The replacement reader is instead used by EF Core as the results of the query. This interceptor also manipulates the command text. This manipulation is not required, but improves clarity in log messages. The command text does not need to be valid SQL since the query is now not going to be executed. @@ -392,7 +392,7 @@ Notice from the log output that the application continues to use the cached mess > [!TIP] > You can [download the SaveChanges interceptor sample](https://github.com/dotnet/EntityFramework.Docs/tree/main/samples/core/Miscellaneous/SaveChangesInterception) from GitHub. - and interception points are defined by the interface. As for other interceptors, the base class with no-op methods is provided as a convenience. + and interception points are defined by the interface. As for other interceptors, the base class with no-op methods is provided as a convenience. > [!TIP] > Interceptors are powerful. However, in many cases it may be easier to override the SaveChanges method or use the [.NET events for SaveChanges](xref:core/logging-events-diagnostics/events) exposed on DbContext. @@ -493,7 +493,7 @@ The general idea for auditing with the interceptor is: * If SaveChanges succeeds, then the audit message is updated to indicate success * If SaveChanges fails, then the audit message is updated to indicate the failure -The first stage is handled before any changes are sent to the database using overrides of and . +The first stage is handled before any changes are sent to the database using overrides of and . [!code-csharp[LogToConsole](../../../samples/core/Miscellaneous/Logging/SimpleLogging/Program.cs?name=LogToConsole)] -Alternately, `LogTo` can be called as part of or when creating a instance to pass to the `DbContext` constructor. +Alternately, `LogTo` can be called as part of or when creating a instance to pass to the `DbContext` constructor. > [!TIP] > OnConfiguring is still called when AddDbContext is used or a DbContextOptions instance is passed to the DbContext constructor. This makes it the ideal place to apply context configuration regardless of how the DbContext is constructed. @@ -35,13 +35,13 @@ Alternately, `LogTo` can be called as part of delegate that accepts a string. EF Core will call this delegate with a string for each log message generated. It is then up to the delegate to do something with the given message. +`LogTo` requires an delegate that accepts a string. EF Core will call this delegate with a string for each log message generated. It is then up to the delegate to do something with the given message. -The method is often used for this delegate, as shown above. This results in each log message being written to the console. +The method is often used for this delegate, as shown above. This results in each log message being written to the console. ### Logging to the debug window - can be used to send output to the Debug window in Visual Studio or other IDEs. [Lambda syntax](/dotnet/csharp/language-reference/operators/lambda-expressions) must be used in this case because the `Debug` class is compiled out of release builds. For example: + can be used to send output to the Debug window in Visual Studio or other IDEs. [Lambda syntax](/dotnet/csharp/language-reference/operators/lambda-expressions) must be used in this case because the `Debug` class is compiled out of release builds. For example: [!code-csharp[BookEntityType](../../../samples/core/Miscellaneous/NewInEFCore6/EntityTypeConfigurationAttributeSample.cs?name=BookEntityType)] -This attribute means that EF Core will use the specified `IEntityTypeConfiguration` implementation whenever the `Book` entity type is included in a model. The entity type is included in a model using one of the normal mechanisms. For example, by creating a property for the entity type: +This attribute means that EF Core will use the specified `IEntityTypeConfiguration` implementation whenever the `Book` entity type is included in a model. The entity type is included in a model using one of the normal mechanisms. For example, by creating a property for the entity type: [!code-csharp[DbContext](../../../samples/core/Miscellaneous/NewInEFCore6/EntityTypeConfigurationAttributeSample.cs?name=DbContext)] -Or by registering it in : +Or by registering it in : ```csharp protected override void OnModelCreating(ModelBuilder modelBuilder) diff --git a/entity-framework/core/modeling/keyless-entity-types.md b/entity-framework/core/modeling/keyless-entity-types.md index 4dc89282e4..f1c22e0799 100644 --- a/entity-framework/core/modeling/keyless-entity-types.md +++ b/entity-framework/core/modeling/keyless-entity-types.md @@ -94,4 +94,4 @@ Finally, we can query the database view in the standard way: > Note we have also defined a context level query property (DbSet) to act as a root for queries against this type. > [!TIP] -> To test keyless entity types mapped to views using the in-memory provider, map them to a query via . See the [in-memory provider docs](xref:core/testing/testing-without-the-database#in-memory-provider) for more information. +> To test keyless entity types mapped to views using the in-memory provider, map them to a query via . See the [in-memory provider docs](xref:core/testing/testing-without-the-database#in-memory-provider) for more information. diff --git a/entity-framework/core/modeling/relationships/navigations.md b/entity-framework/core/modeling/relationships/navigations.md index 44ede4e862..1200dcd177 100644 --- a/entity-framework/core/modeling/relationships/navigations.md +++ b/entity-framework/core/modeling/relationships/navigations.md @@ -35,7 +35,7 @@ Reference navigations for required relationships can be nullable or non-nullable ## Collection navigations -Collection navigations are instances of a .NET collection type; that is, any type implementing . The collection contains instances of the related entity type, of which there can be any number. They represent the "many" side(s) of [one-to-many](xref:core/modeling/relationships/one-to-many) and [many-to-many](xref:core/modeling/relationships/many-to-many) relationships. For example: +Collection navigations are instances of a .NET collection type; that is, any type implementing . The collection contains instances of the related entity type, of which there can be any number. They represent the "many" side(s) of [one-to-many](xref:core/modeling/relationships/one-to-many) and [many-to-many](xref:core/modeling/relationships/many-to-many) relationships. For example: ```csharp public ICollection ThePosts { get; set; } @@ -52,14 +52,14 @@ public ICollection ThePosts { get; } = new List(); ### Collection types -The underlying collection instance must implement , and must have a working `Add` method. It is common to use or . `List` is efficient for small numbers of related entities and maintains a stable ordering. `HashSet` has more efficient lookups for large numbers of entities, but does not have stable ordering. You can also use your own custom collection implementation. +The underlying collection instance must implement , and must have a working `Add` method. It is common to use or . `List` is efficient for small numbers of related entities and maintains a stable ordering. `HashSet` has more efficient lookups for large numbers of entities, but does not have stable ordering. You can also use your own custom collection implementation. > [!IMPORTANT] > The collection must use reference equality. When creating a `HashSet` for a collection navigation, make sure to use . Arrays cannot be used for collection navigations because, even though they implement `ICollection`, the `Add` method throws an exception when called. -Even though the collection instance must be an `ICollection`, the collection does not need to be exposed as such. For example, it is common to expose the navigation as an , which provides a read-only view that cannot be randomly modified by application code. For example: +Even though the collection instance must be an `ICollection`, the collection does not need to be exposed as such. For example, it is common to expose the navigation as an , which provides a read-only view that cannot be randomly modified by application code. For example: ```csharp public class Blog @@ -135,7 +135,7 @@ If EF needs to add an entity to a collection navigation, for example, while exec - Otherwise, an exception is thrown. > [!NOTE] -> If [notification entities](xref:core/change-tracking/change-detection#notification-entities), including [change-tracking proxies](xref:core/change-tracking/change-detection#change-tracking-proxies), are being used, then and are used in place of `List` and `HashSet`. +> If [notification entities](xref:core/change-tracking/change-detection#notification-entities), including [change-tracking proxies](xref:core/change-tracking/change-detection#change-tracking-proxies), are being used, then and are used in place of `List` and `HashSet`. > [!IMPORTANT] > As described in the [change tracking documentation](xref:core/change-tracking/identity-resolution), EF only tracks a single instance of any entity with a given key value. This means that collections used as navigations must use [reference equality semantics](/dotnet/csharp/language-reference/operators/equality-operators). Entity types that don't override object equality will get this by default. Make sure to use when creating a `HashSet` for use as a navigation to ensure it works for all entity types. diff --git a/entity-framework/core/modeling/shadow-properties.md b/entity-framework/core/modeling/shadow-properties.md index f8ef0f8f72..0a8f7ff72f 100644 --- a/entity-framework/core/modeling/shadow-properties.md +++ b/entity-framework/core/modeling/shadow-properties.md @@ -23,7 +23,7 @@ For example, the following code listing will result in a `BlogId` shadow propert ## Configuring shadow properties -You can use the [Fluent API](xref:core/modeling/index#use-fluent-api-to-configure-a-model) to configure shadow properties. Once you have called the string overload of , 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: +You can use the [Fluent API](xref:core/modeling/index#use-fluent-api-to-configure-a-model) to configure shadow properties. Once you have called the string overload of , 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)] diff --git a/entity-framework/core/modeling/value-comparers.md b/entity-framework/core/modeling/value-comparers.md index 25233d3a5a..e6b9940dc6 100644 --- a/entity-framework/core/modeling/value-comparers.md +++ b/entity-framework/core/modeling/value-comparers.md @@ -13,7 +13,7 @@ uid: core/modeling/value-comparers ## Background -[Change tracking](xref:core/change-tracking/index) means that EF Core automatically determines what changes were performed by the application on a loaded entity instance, so that those changes can be saved back to the database when is called. EF Core usually performs this by taking a *snapshot* of the instance when it's loaded from the database, and *comparing* that snapshot to the instance handed out to the application. +[Change tracking](xref:core/change-tracking/index) means that EF Core automatically determines what changes were performed by the application on a loaded entity instance, so that those changes can be saved back to the database when is called. EF Core usually performs this by taking a *snapshot* of the instance when it's loaded from the database, and *comparing* that snapshot to the instance handed out to the application. EF Core comes with built-in logic for snapshotting and comparing most standard types used in databases, so users don't usually need to worry about this topic. However, when a property is mapped through a [value converter](xref:core/modeling/value-conversions), EF Core needs to perform comparison on arbitrary user types, which may be complex. By default, EF Core uses the default equality comparison defined by types (e.g. the `Equals` method); for snapshotting, [value types](/dotnet/csharp/language-reference/builtin-types/value-types) are copied to produce the snapshot, while for [reference types](/dotnet/csharp/language-reference/keywords/reference-types) no copying occurs, and the same instance is used as the snapshot. @@ -34,7 +34,7 @@ Consider byte arrays, which can be arbitrarily large. These could be compared: * By reference, such that a difference is only detected if a new byte array is used * By deep comparison, such that mutation of the bytes in the array is detected -By default, EF Core uses the first of these approaches for non-key byte arrays. That is, only references are compared and a change is detected only when an existing byte array is replaced with a new one. This is a pragmatic decision that avoids copying entire arrays and comparing them byte-to-byte when executing . It means that the common scenario of replacing, say, one image with another is handled in a performant way. +By default, EF Core uses the first of these approaches for non-key byte arrays. That is, only references are compared and a change is detected only when an existing byte array is replaced with a new one. This is a pragmatic decision that avoids copying entire arrays and comparing them byte-to-byte when executing . It means that the common scenario of replacing, say, one image with another is handled in a performant way. On the other hand, reference equality would not work when byte arrays are used to represent binary keys, since it's very unlikely that an FK property is set to the *same instance* as a PK property to which it needs to be compared. Therefore, EF Core uses deep comparisons for byte arrays acting as keys; this is unlikely to have a big performance hit since binary keys are usually short. @@ -71,7 +71,7 @@ It is recommended that you use immutable types (classes or structs) with value c [!code-csharp[ListProperty](../../../samples/core/Modeling/ValueConversions/MappingListProperty.cs?name=ListProperty)] -The class: +The class: * Has reference equality; two lists containing the same values are treated as different. * Is mutable; values in the list can be added and removed. @@ -88,7 +88,7 @@ A typical value conversion on a list property might convert the list to and from *** -The constructor accepts three expressions: +The constructor accepts three expressions: * An expression for checking equality * An expression for generating a hash code @@ -107,10 +107,10 @@ The snapshot is created by cloning the list with `ToList`. Again, this is only n The background section covers why key comparisons may require special semantics. Make sure to create a comparer that is appropriate for keys when setting it on a primary, principal, or foreign key property. -Use in the rare cases where different semantics is required on the same property. +Use in the rare cases where different semantics is required on the same property. > [!NOTE] -> has been obsoleted. Use instead. +> has been obsoleted. Use instead. ## Overriding the default comparer diff --git a/entity-framework/core/modeling/value-conversions.md b/entity-framework/core/modeling/value-conversions.md index 77b6812842..bc5edcfd63 100644 --- a/entity-framework/core/modeling/value-conversions.md +++ b/entity-framework/core/modeling/value-conversions.md @@ -19,11 +19,11 @@ Value converters are specified in terms of a `ModelClrType` and a `ProviderClrTy Conversions are defined using two `Func` expression trees: one from `ModelClrType` to `ProviderClrType` and the other from `ProviderClrType` to `ModelClrType`. Expression trees are used so that they can be compiled into the database access delegate for efficient conversions. The expression tree may contain a simple call to a conversion method for complex conversions. > [!NOTE] -> A property that has been configured for value conversion may also need to specify a . See the examples below, and the [Value Comparers](xref:core/modeling/value-comparers) documentation for more information. +> A property that has been configured for value conversion may also need to specify a . See the examples below, and the [Value Comparers](xref:core/modeling/value-comparers) documentation for more information. ## Configuring a value converter -Value conversions are configured in . For example, consider an enum and entity type defined as: +Value conversions are configured in . For example, consider an enum and entity type defined as: [!code-csharp[BeastAndRider](../../../samples/core/Modeling/ValueConversions/EnumToStringConversions.cs?name=BeastAndRider)] -Conversions can be configured in to store the enum values as strings such as "Donkey", "Mule", etc. in the database; you simply need to provide one function which converts from the `ModelClrType` to the `ProviderClrType`, and another for the opposite conversion: +Conversions can be configured in to store the enum values as strings such as "Donkey", "Mule", etc. in the database; you simply need to provide one function which converts from the `ModelClrType` to the `ProviderClrType`, and another for the opposite conversion: [!code-csharp[ConversionByBuiltInBoolToInt](../../../samples/core/Modeling/ValueConversions/EnumToStringConversions.cs?name=ConversionByBuiltInBoolToInt)] -This is functionally the same as creating an instance of the built-in and setting it explicitly: +This is functionally the same as creating an instance of the built-in and setting it explicitly: [!code-csharp[ConfigurePrimitiveCollection](../../../samples/core/Modeling/ValueConversions/PrimitiveCollection.cs?name=ConfigurePrimitiveCollection)] -`ICollection` represents a mutable reference type. This means that a is needed so that EF Core can track and detect changes correctly. See [Value Comparers](xref:core/modeling/value-comparers) for more information. +`ICollection` represents a mutable reference type. This means that a is needed so that EF Core can track and detect changes correctly. See [Value Comparers](xref:core/modeling/value-comparers) for more information. ### Collections of value objects @@ -547,7 +547,7 @@ And again use serialization to store this: [!code-csharp[ConfigureValueObjectCollection](../../../samples/core/Modeling/ValueConversions/ValueObjectCollection.cs?name=ConfigureValueObjectCollection)] > [!NOTE] -> As before, this conversion requires a . See [Value Comparers](xref:core/modeling/value-comparers) for more information. +> As before, this conversion requires a . See [Value Comparers](xref:core/modeling/value-comparers) for more information. ### Value objects as keys @@ -647,7 +647,7 @@ This can be mapped to a SQL server `rowversion` column using a value converter: ### Specify the DateTime.Kind when reading dates -SQL Server discards the flag when storing a as a [`datetime`](/sql/t-sql/data-types/datetime-transact-sql) or [`datetime2`](/sql/t-sql/data-types/datetime2-transact-sql). This means that DateTime values coming back from the database always have a of `Unspecified`. +SQL Server discards the flag when storing a as a [`datetime`](/sql/t-sql/data-types/datetime-transact-sql) or [`datetime2`](/sql/t-sql/data-types/datetime2-transact-sql). This means that DateTime values coming back from the database always have a of `Unspecified`. Value converters can be used in two ways to deal with this. First, EF Core has a value converter that creates an 8-byte opaque value which preserves the `Kind` flag. For example: diff --git a/entity-framework/core/performance/advanced-performance-topics.md b/entity-framework/core/performance/advanced-performance-topics.md index 164759812c..4ce3e30638 100644 --- a/entity-framework/core/performance/advanced-performance-topics.md +++ b/entity-framework/core/performance/advanced-performance-topics.md @@ -15,13 +15,13 @@ Note that context pooling is orthogonal to database connection pooling, which is ### [With dependency injection](#tab/with-di) -The typical pattern in an ASP.NET Core app using EF Core involves registering a custom type into the [dependency injection](/aspnet/core/fundamentals/dependency-injection) container via . Then, instances of that type are obtained through constructor parameters in controllers or Razor Pages. +The typical pattern in an ASP.NET Core app using EF Core involves registering a custom type into the [dependency injection](/aspnet/core/fundamentals/dependency-injection) container via . Then, instances of that type are obtained through constructor parameters in controllers or Razor Pages. -To enable context pooling, simply replace `AddDbContext` with : +To enable context pooling, simply replace `AddDbContext` with : [!code-csharp[Main](../../../samples/core/Performance/AspNetContextPooling/Program.cs#AddDbContextPool)] -The `poolSize` parameter of sets the maximum number of instances retained by the pool (defaults to 1024). Once `poolSize` is exceeded, new context instances are not cached and EF falls back to the non-pooling behavior of creating instances on demand. +The `poolSize` parameter of sets the maximum number of instances retained by the pool (defaults to 1024). Once `poolSize` is exceeded, new context instances are not cached and EF falls back to the non-pooling behavior of creating instances on demand. ### [Without dependency injection](#tab/without-di) @@ -92,7 +92,7 @@ EF supports *compiled queries*, which allow the explicit compilation of a LINQ q | WithCompiledQuery | 10 | 645.3 us | 10.00 us | 9.35 us | 2.9297 | 13 KB | | WithoutCompiledQuery | 10 | 709.8 us | 25.20 us | 73.10 us | 3.9063 | 18 KB | -To use compiled queries, first compile a query with as follows (use for synchronous queries): +To use compiled queries, first compile a query with as follows (use for synchronous queries): [!code-csharp[Main](../../../samples/core/Performance/Other/Program.cs#CompiledQueryCompile)] diff --git a/entity-framework/core/performance/efficient-querying.md b/entity-framework/core/performance/efficient-querying.md index e4eab9de86..2e9756d17b 100644 --- a/entity-framework/core/performance/efficient-querying.md +++ b/entity-framework/core/performance/efficient-querying.md @@ -156,7 +156,7 @@ Whether a query buffers or streams depends on how it is evaluated: If your queries return just a few results, then you probably don't have to worry about this. However, if your query might return large numbers of rows, it's worth giving thought to streaming instead of buffering. > [!NOTE] -> Avoid using or if you intend to use another LINQ operator on the result - this will needlessly buffer all results into memory. Use instead. +> Avoid using or if you intend to use another LINQ operator on the result - this will needlessly buffer all results into memory. Use instead. ### Internal buffering by EF @@ -165,16 +165,16 @@ In certain situations, EF will itself buffer the resultset internally, regardles * When a retrying execution strategy is in place. This is done to make sure the same results are returned if the query is retried later. * When [split query](xref:core/querying/single-split-queries) is used, the resultsets of all but the last query are buffered - unless MARS (Multiple Active Result Sets) is enabled on SQL Server. This is because it is usually impossible to have multiple query resultsets active at the same time. -Note that this internal buffering occurs in addition to any buffering you cause via LINQ operators. For example, if you use on a query and a retrying execution strategy is in place, the resultset is loaded into memory *twice*: once internally by EF, and once by . +Note that this internal buffering occurs in addition to any buffering you cause via LINQ operators. For example, if you use on a query and a retrying execution strategy is in place, the resultset is loaded into memory *twice*: once internally by EF, and once by . ## Tracking, no-tracking and identity resolution It's recommended to read [the dedicated page on tracking and no-tracking](xref:core/querying/tracking) before continuing with this section. -EF tracks entity instances by default, so that changes on them are detected and persisted when is called. Another effect of tracking queries is that EF detects if an instance has already been loaded for your data, and will automatically return that tracked instance rather than returning a new one; this is called *identity resolution*. From a performance perspective, change tracking means the following: +EF tracks entity instances by default, so that changes on them are detected and persisted when is called. Another effect of tracking queries is that EF detects if an instance has already been loaded for your data, and will automatically return that tracked instance rather than returning a new one; this is called *identity resolution*. From a performance perspective, change tracking means the following: * EF internally maintains a dictionary of tracked instances. When new data is loaded, EF checks the dictionary to see if an instance is already tracked for that entity's key (identity resolution). The dictionary maintenance and lookups take up some time when loading the query's results. -* Before handing a loaded instance to the application, EF *snapshots* that instance and keeps the snapshot internally. When is called, the application's instance is compared with the snapshot to discover the changes to be persisted. The snapshot takes up more memory, and the snapshotting process itself takes time; it's sometimes possible to specify different, possibly more efficient snapshotting behavior via [value comparers](xref:core/modeling/value-comparers), or to use change-tracking proxies to bypass the snapshotting process altogether (though that comes with its own set of disadvantages). +* Before handing a loaded instance to the application, EF *snapshots* that instance and keeps the snapshot internally. When is called, the application's instance is compared with the snapshot to discover the changes to be persisted. The snapshot takes up more memory, and the snapshotting process itself takes time; it's sometimes possible to specify different, possibly more efficient snapshotting behavior via [value comparers](xref:core/modeling/value-comparers), or to use change-tracking proxies to bypass the snapshotting process altogether (though that comes with its own set of disadvantages). In read-only scenarios where changes aren't saved back to the database, the above overheads can be avoided by using [no-tracking queries](xref:core/querying/tracking#no-tracking-queries). However, since no-tracking queries do not perform identity resolution, a database row which is referenced by multiple other loaded rows will be materialized as different instances. @@ -193,7 +193,7 @@ Finally, it is possible to perform updates without the overhead of change tracki In some cases, more optimized SQL exists for your query, which EF does not generate. This can happen when the SQL construct is an extension specific to your database that's unsupported, or simply because EF does not translate to it yet. In these cases, writing SQL by hand can provide a substantial performance boost, and EF supports several ways to do this. -* Use SQL queries [directly in your query](xref:core/querying/sql-queries), e.g. via . EF even lets you compose over the SQL with regular LINQ queries, allowing you to express only a part of the query in SQL. This is a good technique when the SQL only needs to be used in a single query in your codebase. +* Use SQL queries [directly in your query](xref:core/querying/sql-queries), e.g. via . EF even lets you compose over the SQL with regular LINQ queries, allowing you to express only a part of the query in SQL. This is a good technique when the SQL only needs to be used in a single query in your codebase. * Define a [user-defined function](xref:core/querying/database-functions) (UDF), and then call that from your queries. Note that EF allows UDFs to return full resultsets - these are known as table-valued functions (TVFs) - and also allows mapping a `DbSet` to a function, making it look just like just another table. * Define a database view and query from it in your queries. Note that unlike functions, views cannot accept parameters. @@ -202,7 +202,7 @@ In some cases, more optimized SQL exists for your query, which EF does not gener ## Asynchronous programming -As a general rule, in order for your application to be scalable, it's important to always use asynchronous APIs rather than synchronous one (e.g. rather than ). Synchronous APIs block the thread for the duration of database I/O, increasing the need for threads and the number of thread context switches that must occur. +As a general rule, in order for your application to be scalable, it's important to always use asynchronous APIs rather than synchronous one (e.g. rather than ). Synchronous APIs block the thread for the duration of database I/O, increasing the need for threads and the number of thread context switches that must occur. For more information, see the page on [async programming](xref:core/miscellaneous/async). diff --git a/entity-framework/core/performance/efficient-updating.md b/entity-framework/core/performance/efficient-updating.md index 97e8e91eab..842aab9b1d 100644 --- a/entity-framework/core/performance/efficient-updating.md +++ b/entity-framework/core/performance/efficient-updating.md @@ -13,7 +13,7 @@ EF Core helps minimize roundtrips by automatically batching together all updates [!code-csharp[Main](../../../samples/core/Performance/Other/Program.cs#SaveChangesBatching)] -The above loads a blog from the database, changes its URL, and then adds two new blogs; to apply this, two SQL INSERT statements and one UPDATE statement are sent to the database. Rather than sending them one by one, as Blog instances are added, EF Core tracks these changes internally, and executes them in a single roundtrip when is called. +The above loads a blog from the database, changes its URL, and then adds two new blogs; to apply this, two SQL INSERT statements and one UPDATE statement are sent to the database. Rather than sending them one by one, as Blog instances are added, EF Core tracks these changes internally, and executes them in a single roundtrip when is called. The number of statements that EF batches in a single roundtrip depends on the database provider being used. For example, performance analysis has shown batching to be generally less efficient for SQL Server when less than 4 statements are involved. Similarly, the benefits of batching degrade after around 40 statements for SQL Server, so EF Core will by default only execute up to 42 statements in a single batch, and execute additional statements in separate roundtrips. diff --git a/entity-framework/core/providers/cosmos/modeling.md b/entity-framework/core/providers/cosmos/modeling.md index 2406943d1c..2ceebf6728 100644 --- a/entity-framework/core/providers/cosmos/modeling.md +++ b/entity-framework/core/providers/cosmos/modeling.md @@ -11,13 +11,13 @@ uid: core/providers/cosmos/modeling In Azure Cosmos DB, JSON documents are stored in containers. Unlike tables in relational databases, Azure Cosmos DB containers can contain documents with different shapes - a container does not impose a uniform schema on its documents. However, various configuration options are defined at the container level, and therefore affect all documents contained within it. See the [Azure Cosmos DB documentation on containers](/azure/cosmos-db/resource-model) for more information. -By default, EF maps all entity types to the same container; this is usually a good default in terms of performance and pricing. The default container is named after the .NET context type (`OrderContext` in this case). To change the default container name, use : +By default, EF maps all entity types to the same container; this is usually a good default in terms of performance and pricing. The default container is named after the .NET context type (`OrderContext` in this case). To change the default container name, use : ```csharp modelBuilder.HasDefaultContainer("Store"); ``` -To map an entity type to a different container use : +To map an entity type to a different container use : ```csharp modelBuilder.Entity().ToContainer("Orders"); @@ -27,7 +27,7 @@ Before mapping entity types to different containers, make sure you understand th ## IDs and keys -Azure Cosmos DB requires all documents to have an `id` JSON property which uniquely identifies them. Like other EF providers, the EF Azure Cosmos DB provider will attempt to find a property named `Id` or `Id`, and configure that property as the key of your entity type, mapping it to the `id` JSON property. You can configure any property to be the key property by using ; see [the general EF documentation on keys](xref:core/modeling/keys) for more information. +Azure Cosmos DB requires all documents to have an `id` JSON property which uniquely identifies them. Like other EF providers, the EF Azure Cosmos DB provider will attempt to find a property named `Id` or `Id`, and configure that property as the key of your entity type, mapping it to the `id` JSON property. You can configure any property to be the key property by using ; see [the general EF documentation on keys](xref:core/modeling/keys) for more information. Developers coming to Azure Cosmos DB from other databases sometimes expect the key (`Id`) property to be generated automatically. For example, on SQL Server, EF configures numeric key properties to be IDENTITY columns, where auto-incrementing values are generated in the database. In contrast, Azure Cosmos DB does not support automatic generation of properties, and so key properties must be explicitly set. Inserting an entity type with an unset key property will simply insert the CLR default value for that property (e.g. 0 for `int`), and a second insert will fail; EF issues a warning if you attempt to do this. @@ -95,7 +95,7 @@ This is similar, but allows EF to use efficient [point reads](xref:core/provider ## Provisioned throughput -If you use EF Core to create the Azure Cosmos DB database or containers you can configure [provisioned throughput](/azure/cosmos-db/set-throughput) for the database by calling or . For example: +If you use EF Core to create the Azure Cosmos DB database or containers you can configure [provisioned throughput](/azure/cosmos-db/set-throughput) for the database by calling or . For example: [!code-csharp[ModelThroughput](../../../../samples/core/Miscellaneous/NewInEFCore6.Cosmos/CosmosModelConfigurationSample.cs?name=ModelThroughput)] -To configure provisioned throughput for a container call or . For example: +To configure provisioned throughput for a container call or . For example: [!code-csharp[BookConfiguration](../../../../samples/core/Miscellaneous/NewInEFCore6/EntityTypeConfigurationAttributeSample.cs?name=BookConfiguration)] -Normally, this configuration class must be instantiated and called into from . For example: +Normally, this configuration class must be instantiated and called into from . For example: ```csharp protected override void OnModelCreating(ModelBuilder modelBuilder) @@ -2728,7 +2728,7 @@ public class Book --> [!code-csharp[BookEntityType](../../../../samples/core/Miscellaneous/NewInEFCore6/EntityTypeConfigurationAttributeSample.cs?name=BookEntityType)] -This attribute means that EF Core will use the specified `IEntityTypeConfiguration` implementation whenever the `Book` entity type is included in a model. The entity type is included in a model using one of the normal mechanisms. For example, by creating a property for the entity type: +This attribute means that EF Core will use the specified `IEntityTypeConfiguration` implementation whenever the `Book` entity type is included in a model. The entity type is included in a model using one of the normal mechanisms. For example, by creating a property for the entity type: [!code-csharp[DbContext](../../../../samples/core/Miscellaneous/NewInEFCore6/EntityTypeConfigurationAttributeSample.cs?name=DbContext)] -Or by registering it in : +Or by registering it in : ```csharp protected override void OnModelCreating(ModelBuilder modelBuilder) @@ -2775,7 +2775,7 @@ SQL Server [sparse columns](/sql/relational-databases/tables/use-sparse-columns) --> [!code-csharp[UserEntityType](../../../../samples/core/Miscellaneous/NewInEFCore6/SparseColumnsSample.cs?name=UserEntityType)] -There may be millions of users, with only a handful of these being moderators. This means mapping the `ForumName` as sparse might make sense here. This can now be configured using `IsSparse` in . For example: +There may be millions of users, with only a handful of these being moderators. This means mapping the `ForumName` as sparse might make sense here. This can now be configured using `IsSparse` in . For example: [!code-csharp[LookupByAnyProperty](../../../../samples/core/Miscellaneous/NewInEFCore8/LookupByKeySample.cs?name=LookupByAnyProperty)] -This lookup requires a scan of all tracked `Post` instances, and so will be less efficient than key lookups. However, it is usually still faster than naive queries using . +This lookup requires a scan of all tracked `Post` instances, and so will be less efficient than key lookups. However, it is usually still faster than naive queries using . Finally, it is also possible to perform lookups against composite keys, other combinations of multiple properties, or when the property type is not known at compile time. For example: @@ -2130,7 +2130,7 @@ Queries using `DateOnly` and `TimeOnly` work in the expected manner. For example --> [!code-csharp[OpenSchools](../../../../samples/core/Miscellaneous/NewInEFCore8/DateOnlyTimeOnlySample.cs?name=OpenSchools)] -This query translates to the following SQL, as shown by : +This query translates to the following SQL, as shown by : ```sql DECLARE @__today_0 date = '2023-02-07'; @@ -2173,7 +2173,7 @@ Combining two features from EF8, we can now query for opening hours by indexing --> [!code-csharp[OpenSchoolsJson](../../../../samples/core/Miscellaneous/NewInEFCore8/DateOnlyTimeOnlySample.cs?name=OpenSchoolsJson)] -This query translates to the following SQL, as shown by : +This query translates to the following SQL, as shown by : ```sql DECLARE @__today_0 date = '2023-02-07'; diff --git a/entity-framework/core/what-is-new/ef-core-9.0/breaking-changes.md b/entity-framework/core/what-is-new/ef-core-9.0/breaking-changes.md index b0a47e750b..cfdda27887 100644 --- a/entity-framework/core/what-is-new/ef-core-9.0/breaking-changes.md +++ b/entity-framework/core/what-is-new/ef-core-9.0/breaking-changes.md @@ -416,19 +416,19 @@ Unfortunately, Azure Cosmos DB does not currently support the `OFFSET` and `LIMI ##### Old behavior -Previously, calls to were ignored by the EF Cosmos DB provider. +Previously, calls to were ignored by the EF Cosmos DB provider. ##### New behavior -The provider now throws if is specified. +The provider now throws if is specified. ##### Why -In Azure Cosmos DB, all properties are indexed by default, and no indexing needs to be specified. While it's possible to define a custom indexing policy, this isn't currently supported by EF, and can be done via the Azure Portal without EF support. Since calls weren't doing anything, they are no longer allowed. +In Azure Cosmos DB, all properties are indexed by default, and no indexing needs to be specified. While it's possible to define a custom indexing policy, this isn't currently supported by EF, and can be done via the Azure Portal without EF support. Since calls weren't doing anything, they are no longer allowed. ##### Mitigations -Remove any calls to . +Remove any calls to . diff --git a/entity-framework/core/what-is-new/ef-core-9.0/whatsnew.md b/entity-framework/core/what-is-new/ef-core-9.0/whatsnew.md index a48c9bb0fc..36c45ce656 100644 --- a/entity-framework/core/what-is-new/ef-core-9.0/whatsnew.md +++ b/entity-framework/core/what-is-new/ef-core-9.0/whatsnew.md @@ -79,7 +79,7 @@ To learn more about querying with partition keys and point reads, [see the query Azure Cosmos DB originally supported a single partition key, but has since expanded partitioning capabilities to also support [subpartitioning through the specification of up to three levels of hierarchy in the partition key](/azure/cosmos-db/hierarchical-partition-keys). EF Core 9 brings full support for hierarchical partition keys, allowing you take advantage of the better performance and cost savings associated with this feature. -Partition keys are specified using the model building API, typically in . There must be a mapped property in the entity type for each level of the partition key. For example, consider a `UserSession` entity type: +Partition keys are specified using the model building API, typically in . There must be a mapped property in the entity type for each level of the partition key. For example, consider a `UserSession` entity type: