Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
320 changes: 320 additions & 0 deletions src/EFCore.Cosmos/Extensions/CosmosEntityTypeBuilderExtensions.cs

Large diffs are not rendered by default.

93 changes: 93 additions & 0 deletions src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.EntityFrameworkCore.Cosmos.Metadata;
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;

// ReSharper disable once CheckNamespace
Expand Down Expand Up @@ -344,6 +345,98 @@ public static void SetETagPropertyName(this IMutableEntityType entityType, strin
public static IProperty? GetETagProperty(this IEntityType entityType)
=> (IProperty?)((IReadOnlyEntityType)entityType).GetETagProperty();

/// <summary>
/// Returns a value indicating whether model building will always create a "__id" shadow property mapped to the JSON "id".
/// This was the default behavior before EF Core 9.0.
/// </summary>
/// <param name="entityType">The entity type.</param>
/// <returns>
/// <see langword="true" /> to force __id creation, <see langword="false" /> to not force __id creation,
/// <see langword="null" /> to revert to the default setting.
/// .</returns>
public static bool? GetAlwaysCreateShadowIdProperty(this IReadOnlyEntityType entityType)
=> (entityType.BaseType != null
? entityType.GetRootType().GetAlwaysCreateShadowIdProperty()
: (bool?)entityType[CosmosAnnotationNames.AlwaysCreateShadowIdProperty])
?? entityType.Model.GetAlwaysCreateShadowIdProperty();

/// <summary>
/// Forces model building to always create a "__id" shadow property mapped to the JSON "id". This was the default
/// behavior before EF Core 9.0.
/// </summary>
/// <param name="entityType">The entity type.</param>
/// <param name="alwaysCreate">
/// <see langword="true" /> to force __id creation, <see langword="false" /> to not force __id creation,
/// <see langword="null" /> to revert to the default setting.
/// </param>
public static void SetAlwaysCreateShadowIdProperty(this IMutableEntityType entityType, bool? alwaysCreate)
=> entityType.SetOrRemoveAnnotation(CosmosAnnotationNames.AlwaysCreateShadowIdProperty, alwaysCreate);

/// <summary>
/// Forces model building to always create a "__id" shadow property mapped to the JSON "id". This was the default
/// behavior before EF Core 9.0.
/// </summary>
/// <param name="entityType">The entity type.</param>
/// <param name="alwaysCreate">
/// <see langword="true" /> to force __id creation, <see langword="false" /> to not force __id creation,
/// <see langword="null" /> to revert to the default setting.
/// </param>
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
public static bool? SetAlwaysCreateShadowIdProperty(
this IConventionEntityType entityType,
bool? alwaysCreate,
bool fromDataAnnotation = false)
=> (bool?)entityType.SetOrRemoveAnnotation(
CosmosAnnotationNames.AlwaysCreateShadowIdProperty, alwaysCreate, fromDataAnnotation)?.Value;

/// <summary>
/// Gets the <see cref="ConfigurationSource" /> for <see cref="GetAlwaysCreateShadowIdProperty"/>.
/// </summary>
/// <param name="entityType">The entity typer.</param>
/// <returns>The <see cref="ConfigurationSource" />.</returns>
public static ConfigurationSource? GetAlwaysCreateShadowIdPropertyConfigurationSource(this IConventionEntityType entityType)
=> entityType.FindAnnotation(CosmosAnnotationNames.AlwaysCreateShadowIdProperty)?.GetConfigurationSource();

/// <summary>
/// Returns a value indicating whether the entity type discriminator should be included in the JSON "id" value.
/// Prior to EF Core 9, it was always included. Starting with EF Core 9, it is not included by default.
/// </summary>
/// <param name="entityType">The entity type.</param>
/// <returns>The <see cref="DiscriminatorInKeyBehavior"/> or <see langword="null" /> if not set.</returns>
public static DiscriminatorInKeyBehavior? GetDiscriminatorInKey(this IReadOnlyEntityType entityType)
=> (entityType.BaseType != null
? entityType.GetRootType().GetDiscriminatorInKey()
: (DiscriminatorInKeyBehavior?)entityType[CosmosAnnotationNames.DiscriminatorInKey])
?? entityType.Model.GetDiscriminatorInKey();

/// <summary>
/// Includes the entity type discriminator in the JSON "id".
/// </summary>
/// <param name="entityType">The entity type.</param>
/// <param name="behavior">The behavior to use, or <see langword="null" /> to reset the behavior to the default.</param>
public static void SetDiscriminatorInKey(this IMutableEntityType entityType, DiscriminatorInKeyBehavior? behavior)
=> entityType.SetOrRemoveAnnotation(CosmosAnnotationNames.DiscriminatorInKey, behavior);

/// <summary>
/// Includes the entity type discriminator in the JSON "id".
/// </summary>
/// <param name="entityType">The entity type.</param>
/// <param name="behavior">The behavior to use, or <see langword="null" /> to reset the behavior to the default.</param>
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
public static DiscriminatorInKeyBehavior? SetDiscriminatorInKey(
this IConventionEntityType entityType, DiscriminatorInKeyBehavior? behavior, bool fromDataAnnotation = false)
=> (DiscriminatorInKeyBehavior?)entityType.SetOrRemoveAnnotation(
CosmosAnnotationNames.DiscriminatorInKey, behavior, fromDataAnnotation)?.Value;

/// <summary>
/// Gets the <see cref="ConfigurationSource" /> for <see cref="GetDiscriminatorInKey"/>.
/// </summary>
/// <param name="entityType">The entity typer.</param>
/// <returns>The <see cref="ConfigurationSource" />.</returns>
public static ConfigurationSource? GetDiscriminatorInKeyConfigurationSource(this IConventionEntityType entityType)
=> entityType.FindAnnotation(CosmosAnnotationNames.DiscriminatorInKey)
?.GetConfigurationSource();

/// <summary>
/// Returns the time to live for analytical store in seconds at container scope.
/// </summary>
Expand Down
76 changes: 76 additions & 0 deletions src/EFCore.Cosmos/Extensions/CosmosModelBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.EntityFrameworkCore.Cosmos.Metadata;
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;

// ReSharper disable once CheckNamespace
Expand Down Expand Up @@ -104,6 +105,81 @@ public static ModelBuilder HasManualThroughput(this ModelBuilder modelBuilder, i
return modelBuilder;
}

/// <summary>
/// Forces model building to always create a "__id" shadow property mapped to the JSON "id". This was the default
/// behavior before EF Core 9.0.
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-modeling">Modeling entity types and relationships</see>, and
/// <see href="https://aka.ms/efcore-docs-cosmos">Accessing Azure Cosmos DB with EF Core</see> for more information and examples.
/// </remarks>
/// <param name="modelBuilder">The model builder.</param>
/// <param name="alwaysCreate">
/// <see langword="true" /> to force __id creation, <see langword="false" /> to not force __id creation,
/// <see langword="null" /> to revert to the default setting.
/// </param>
public static ModelBuilder AlwaysCreateShadowIdProperties(this ModelBuilder modelBuilder, bool? alwaysCreate = true)
{
modelBuilder.Model.SetAlwaysCreateShadowIdProperty(alwaysCreate);

return modelBuilder;
}

/// <summary>
/// Includes the discriminator value of the entity type in the JSON "id" value. This was the default behavior before EF Core 9.
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-modeling">Modeling entity types and relationships</see>, and
/// <see href="https://aka.ms/efcore-docs-cosmos">Accessing Azure Cosmos DB with EF Core</see> for more information and examples.
/// </remarks>
/// <param name="modelBuilder">The model builder.</param>
/// <param name="includeDiscriminator">
/// <see langword="true" /> to include the discriminator, <see langword="false" /> to not include the discriminator,
/// <see langword="null" /> to revert to the default setting.
/// </param>
/// <returns>The same builder instance so that multiple calls can be chained.</returns>
public static ModelBuilder IncludeDiscriminatorInJsonId(
this ModelBuilder modelBuilder,
bool? includeDiscriminator = true)
{
modelBuilder.Model.SetDiscriminatorInKey(
includeDiscriminator == null
? null
: includeDiscriminator.Value
? DiscriminatorInKeyBehavior.EntityTypeName
: DiscriminatorInKeyBehavior.None);

return modelBuilder;
}

/// <summary>
/// Includes the discriminator value of the root entity type in the JSON "id" value. This allows types with the same
/// primary key to be saved in the same container, while still allowing "ReadItem" to be used for lookups of an unknown type.
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-modeling">Modeling entity types and relationships</see>, and
/// <see href="https://aka.ms/efcore-docs-cosmos">Accessing Azure Cosmos DB with EF Core</see> for more information and examples.
/// </remarks>
/// <param name="modelBuilder">The model builder.</param>
/// <param name="includeDiscriminator">
/// <see langword="true" /> to include the discriminator, <see langword="false" /> to not include the discriminator,
/// <see langword="null" /> to revert to the default setting.
/// </param>
/// <returns>The same builder instance so that multiple calls can be chained.</returns>
public static ModelBuilder IncludeRootDiscriminatorInJsonId(
this ModelBuilder modelBuilder,
bool? includeDiscriminator = true)
{
modelBuilder.Model.SetDiscriminatorInKey(
includeDiscriminator == null
? null
: includeDiscriminator.Value
? DiscriminatorInKeyBehavior.RootEntityTypeName
: DiscriminatorInKeyBehavior.None);

return modelBuilder;
}

/// <summary>
/// Configures the autoscale provisioned throughput offering.
/// </summary>
Expand Down
86 changes: 86 additions & 0 deletions src/EFCore.Cosmos/Extensions/CosmosModelExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.EntityFrameworkCore.Cosmos.Metadata;
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;

// ReSharper disable once CheckNamespace
Expand Down Expand Up @@ -57,6 +58,91 @@ public static void SetDefaultContainer(this IMutableModel model, string? name)
public static ConfigurationSource? GetDefaultContainerConfigurationSource(this IConventionModel model)
=> model.FindAnnotation(CosmosAnnotationNames.ContainerName)?.GetConfigurationSource();

/// <summary>
/// Returns a value indicating whether the setting for always creating the "__id" property can be set
/// from the current configuration source
/// </summary>
/// <param name="model">The model.</param>
/// <returns>The configured value.</returns>
public static bool? GetAlwaysCreateShadowIdProperty(this IReadOnlyModel model)
=> (bool?)model[CosmosAnnotationNames.AlwaysCreateShadowIdProperty];

/// <summary>
/// Forces model building to always create a "__id" shadow property mapped to the JSON "id". This was the default
/// behavior before EF Core 9.0.
/// </summary>
/// <param name="model">The model.</param>
/// <param name="alwaysCreate">
/// <see langword="true" /> to force __id creation, <see langword="false" /> to not force __id creation,
/// <see langword="null" /> to revert to the default setting.
/// </param>
public static void SetAlwaysCreateShadowIdProperty(this IMutableModel model, bool? alwaysCreate)
=> model.SetOrRemoveAnnotation(CosmosAnnotationNames.AlwaysCreateShadowIdProperty, alwaysCreate);

/// <summary>
/// Forces model building to always create a "__id" shadow property mapped to the JSON "id". This was the default
/// behavior before EF Core 9.0.
/// </summary>
/// <param name="model">The model.</param>
/// <param name="alwaysCreate">
/// <see langword="true" /> to force __id creation, <see langword="false" /> to not force __id creation,
/// <see langword="null" /> to revert to the default setting.
/// </param>
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
public static bool? SetAlwaysCreateShadowIdProperty(
this IConventionModel model,
bool? alwaysCreate,
bool fromDataAnnotation = false)
=> (bool?)model.SetOrRemoveAnnotation(CosmosAnnotationNames.AlwaysCreateShadowIdProperty, alwaysCreate, fromDataAnnotation)?.Value;

/// <summary>
/// Gets the <see cref="ConfigurationSource" />
/// for <see cref="GetAlwaysCreateShadowIdProperty(Microsoft.EntityFrameworkCore.Metadata.IReadOnlyModel)"/>.
/// </summary>
/// <param name="model">The model.</param>
/// <returns>The <see cref="ConfigurationSource" />.</returns>
public static ConfigurationSource? GetAlwaysCreateShadowIdPropertyConfigurationSource(this IConventionModel model)
=> model.FindAnnotation(CosmosAnnotationNames.AlwaysCreateShadowIdProperty)?.GetConfigurationSource();

/// <summary>
/// Returns a value indicating whether the entity type discriminator should be included in the JSON "id" value.
/// Prior to EF Core 9, it was always included. Starting with EF Core 9, it is not included by default.
/// </summary>
/// <param name="model">The model.</param>
/// <returns>The <see cref="DiscriminatorInKeyBehavior"/> or <see langword="null" /> if not set.</returns>
public static DiscriminatorInKeyBehavior? GetDiscriminatorInKey(this IReadOnlyModel model)
=> (DiscriminatorInKeyBehavior?)model[CosmosAnnotationNames.DiscriminatorInKey];

/// <summary>
/// Includes the entity type discriminator in the JSON "id".
/// </summary>
/// <param name="model">The model.</param>
/// <param name="behavior">The behavior to use, or <see langword="null" /> to reset the behavior to the default.</param>
public static void SetDiscriminatorInKey(this IMutableModel model, DiscriminatorInKeyBehavior? behavior)
=> model.SetOrRemoveAnnotation(CosmosAnnotationNames.DiscriminatorInKey, behavior);

/// <summary>
/// Includes the entity type discriminator in the JSON "id".
/// </summary>
/// <param name="model">The model.</param>
/// <param name="behavior">The behavior to use, or <see langword="null" /> to reset the behavior to the default.</param>
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
public static DiscriminatorInKeyBehavior? SetDiscriminatorInKey(
this IConventionModel model,
DiscriminatorInKeyBehavior? behavior,
bool fromDataAnnotation = false)
=> (DiscriminatorInKeyBehavior?)model.SetOrRemoveAnnotation(
CosmosAnnotationNames.DiscriminatorInKey, behavior, fromDataAnnotation)?.Value;

/// <summary>
/// Gets the <see cref="ConfigurationSource" />
/// for <see cref="GetAlwaysCreateShadowIdProperty(Microsoft.EntityFrameworkCore.Metadata.IReadOnlyModel)"/>.
/// </summary>
/// <param name="model">The model.</param>
/// <returns>The <see cref="ConfigurationSource" />.</returns>
public static ConfigurationSource? GetDiscriminatorInKeyConfigurationSource(this IConventionModel model)
=> model.FindAnnotation(CosmosAnnotationNames.DiscriminatorInKey)?.GetConfigurationSource();

/// <summary>
/// Returns the provisioned throughput at database scope.
/// </summary>
Expand Down
Loading