Skip to content

Commit

Permalink
Add Cosmos metadata extensions for conventions
Browse files Browse the repository at this point in the history
Move Discriminator metadata to Core

Part of #214
Part of #13603
  • Loading branch information
ajcvickers authored and AndriySvyryd committed May 14, 2019
1 parent 2daec6a commit d4b0d9d
Show file tree
Hide file tree
Showing 87 changed files with 1,733 additions and 2,205 deletions.
133 changes: 122 additions & 11 deletions src/EFCore.Cosmos/Extensions/CosmosEntityTypeBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@

using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Utilities;

// ReSharper disable once CheckNamespace
Expand All @@ -18,36 +15,150 @@ namespace Microsoft.EntityFrameworkCore
public static class CosmosEntityTypeBuilderExtensions
{
/// <summary>
/// Configures the container that the entity maps to when targeting Azure Cosmos.
/// Configures the container that the entity type maps to when targeting Azure Cosmos.
/// </summary>
/// <param name="entityTypeBuilder"> The builder for the entity type being configured. </param>
/// <param name="name"> The name of the container. </param>
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
public static EntityTypeBuilder ToContainer(
public static EntityTypeBuilder ForCosmosToContainer(
[NotNull] this EntityTypeBuilder entityTypeBuilder,
[CanBeNull] string name)
{
Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder));
Check.NullButNotEmpty(name, nameof(name));

entityTypeBuilder.GetInfrastructure<InternalEntityTypeBuilder>()
.Cosmos(ConfigurationSource.Explicit)
.ToContainer(name);
entityTypeBuilder.Metadata.SetCosmosContainerName(name);

return entityTypeBuilder;
}

/// <summary>
/// Configures the container that the entity maps to when targeting Azure Cosmos.
/// Configures the container that the entity type maps to when targeting Azure Cosmos.
/// </summary>
/// <typeparam name="TEntity"> The entity type being configured. </typeparam>
/// <param name="entityTypeBuilder"> The builder for the entity type being configured. </param>
/// <param name="name"> The name of the container. </param>
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
public static EntityTypeBuilder<TEntity> ToContainer<TEntity>(
public static EntityTypeBuilder<TEntity> ForCosmosToContainer<TEntity>(
[NotNull] this EntityTypeBuilder<TEntity> entityTypeBuilder,
[CanBeNull] string name)
where TEntity : class
=> (EntityTypeBuilder<TEntity>)ToContainer((EntityTypeBuilder)entityTypeBuilder, name);
=> (EntityTypeBuilder<TEntity>)ForCosmosToContainer((EntityTypeBuilder)entityTypeBuilder, name);

/// <summary>
/// Configures the container that the entity type maps to when targeting Azure Cosmos.
/// </summary>
/// <param name="entityTypeBuilder"> The builder for the entity type being configured. </param>
/// <param name="name"> The name of the container. </param>
/// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param>
/// <returns>
/// The same builder instance if the configuration was applied,
/// <c>null</c> otherwise.
/// </returns>
public static IConventionEntityTypeBuilder ForCosmosToContainer(
[NotNull] this IConventionEntityTypeBuilder entityTypeBuilder,
[CanBeNull] string name,
bool fromDataAnnotation = false)
{
if (!entityTypeBuilder.ForCosmosCanSetContainer(name, fromDataAnnotation))
{
return null;
}

entityTypeBuilder.Metadata.SetCosmosContainerName(name, fromDataAnnotation);

return entityTypeBuilder;
}

/// <summary>
/// Returns a value indicating whether the container that the entity type maps to can be set
/// from the current configuration source
/// </summary>
/// <param name="entityTypeBuilder"> The builder for the entity type being configured. </param>
/// <param name="name"> The name of the container. </param>
/// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param>
/// <returns> <c>true</c> if the configuration can be applied. </returns>
public static bool ForCosmosCanSetContainer(
[NotNull] this IConventionEntityTypeBuilder entityTypeBuilder, [CanBeNull] string name, bool fromDataAnnotation = false)
{
Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder));
Check.NullButNotEmpty(name, nameof(name));

return entityTypeBuilder.CanSetAnnotation(CosmosAnnotationNames.ContainerName, name, fromDataAnnotation);
}

/// <summary>
/// Configures the property name that the entity is mapped to when stored as an embedded document.
/// </summary>
/// <param name="entityTypeBuilder"> The builder for the entity type being configured. </param>
/// <param name="name"> The name of the parent property. </param>
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
public static OwnedNavigationBuilder ForCosmosToProperty(
[NotNull] this OwnedNavigationBuilder entityTypeBuilder,
[CanBeNull] string name)
{
entityTypeBuilder.OwnedEntityType.SetCosmosContainingPropertyName(name);

return entityTypeBuilder;
}

/// <summary>
/// Configures the property name that the entity is mapped to when stored as an embedded document.
/// </summary>
/// <param name="entityTypeBuilder"> The builder for the entity type being configured. </param>
/// <param name="name"> The name of the parent property. </param>
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
public static OwnedNavigationBuilder<TEntity, TDependentEntity> ForCosmosToProperty<TEntity, TDependentEntity>(
[NotNull] this OwnedNavigationBuilder<TEntity, TDependentEntity> entityTypeBuilder,
[CanBeNull] string name)
where TEntity : class
where TDependentEntity : class
{
entityTypeBuilder.OwnedEntityType.SetCosmosContainingPropertyName(name);

return entityTypeBuilder;
}

/// <summary>
/// Configures the property name that the entity is mapped to when stored as an embedded document.
/// </summary>
/// <param name="entityTypeBuilder"> The builder for the entity type being configured. </param>
/// <param name="name"> The name of the parent property. </param>
/// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param>
/// <returns>
/// The same builder instance if the configuration was applied,
/// <c>null</c> otherwise.
/// </returns>
public static IConventionEntityTypeBuilder ForCosmosToProperty(
[NotNull] this IConventionEntityTypeBuilder entityTypeBuilder,
[CanBeNull] string name,
bool fromDataAnnotation = false)
{
if (!entityTypeBuilder.ForCosmosCanSetProperty(name, fromDataAnnotation))
{
return null;
}

entityTypeBuilder.Metadata.SetCosmosContainingPropertyName(name, fromDataAnnotation);

return entityTypeBuilder;
}

/// <summary>
/// Returns a value indicating whether the parent property name to which the entity type is mapped to can be set
/// from the current configuration source
/// </summary>
/// <param name="entityTypeBuilder"> The builder for the entity type being configured. </param>
/// <param name="name"> The name of the parent property. </param>
/// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param>
/// <returns> <c>true</c> if the configuration can be applied. </returns>
public static bool ForCosmosCanSetProperty(
[NotNull] this IConventionEntityTypeBuilder entityTypeBuilder, [CanBeNull] string name, bool fromDataAnnotation = false)
{
Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder));
Check.NullButNotEmpty(name, nameof(name));

return entityTypeBuilder.CanSetAnnotation(CosmosAnnotationNames.PropertyName, name, fromDataAnnotation);
}
}
}
108 changes: 108 additions & 0 deletions src/EFCore.Cosmos/Extensions/CosmosEntityTypeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;

// ReSharper disable once CheckNamespace
namespace Microsoft.EntityFrameworkCore
{
/// <summary>
/// Extension methods for <see cref="IEntityType" /> for Cosmos metadata.
/// </summary>
public static class CosmosEntityTypeExtensions
{
/// <summary>
/// Returns the name of the container to which the entity type is mapped.
/// </summary>
/// <param name="entityType"> The entity type to get the container name for. </param>
/// <returns> The name of the container to which the entity type is mapped. </returns>
public static string GetCosmosContainerName([NotNull] this IEntityType entityType) =>
entityType.BaseType != null
? entityType.RootType().GetCosmosContainerName()
: (string)entityType[CosmosAnnotationNames.ContainerName]
?? GetCosmosDefaultContainerName(entityType);

private static string GetCosmosDefaultContainerName(IEntityType entityType)
=> entityType.Model.GetCosmosDefaultContainerName()
?? entityType.ShortName();

/// <summary>
/// Sets the name of the container to which the entity type is mapped.
/// </summary>
/// <param name="entityType"> The entity type to set the container name for. </param>
/// <param name="name"> The name to set. </param>
public static void SetCosmosContainerName([NotNull] this IMutableEntityType entityType, [CanBeNull] string name)
=> entityType.SetOrRemoveAnnotation(
CosmosAnnotationNames.ContainerName,
Check.NullButNotEmpty(name, nameof(name)));

/// <summary>
/// Sets the name of the container to which the entity type is mapped.
/// </summary>
/// <param name="entityType"> The entity type to set the container name for. </param>
/// <param name="name"> The name to set. </param>
/// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param>
public static void SetCosmosContainerName(
[NotNull] this IConventionEntityType entityType, [CanBeNull] string name, bool fromDataAnnotation = false)
=> entityType.SetOrRemoveAnnotation(
CosmosAnnotationNames.ContainerName,
Check.NullButNotEmpty(name, nameof(name)),
fromDataAnnotation);

/// <summary>
/// Gets the <see cref="ConfigurationSource" /> for the container to which the entity type is mapped.
/// </summary>
/// <param name="entityType"> The entity type to find configuration source for. </param>
/// <returns> The <see cref="ConfigurationSource" /> for the container to which the entity type is mapped. </returns>
public static ConfigurationSource? GetCosmosContainerNameConfigurationSource([NotNull] this IConventionEntityType entityType)
=> entityType.FindAnnotation(CosmosAnnotationNames.ContainerName)
?.GetConfigurationSource();

/// <summary>
/// Returns the name of the parent property to which the entity type is mapped.
/// </summary>
/// <param name="entityType"> The entity type to get the containing property name for. </param>
/// <returns> The name of the parent property to which the entity type is mapped. </returns>
public static string GetCosmosContainingPropertyName([NotNull] this IEntityType entityType) =>
entityType[CosmosAnnotationNames.PropertyName] as string
?? GetDefaultContainingPropertyName(entityType);

private static string GetDefaultContainingPropertyName(IEntityType entityType)
=> entityType.FindOwnership()?.PrincipalToDependent.Name;

/// <summary>
/// Sets the name of the parent property to which the entity type is mapped.
/// </summary>
/// <param name="entityType"> The entity type to set the containing property name for. </param>
/// <param name="name"> The name to set. </param>
public static void SetCosmosContainingPropertyName([NotNull] this IMutableEntityType entityType, [CanBeNull] string name)
=> entityType.SetOrRemoveAnnotation(
CosmosAnnotationNames.PropertyName,
Check.NullButNotEmpty(name, nameof(name)));

/// <summary>
/// Sets the name of the parent property to which the entity type is mapped.
/// </summary>
/// <param name="entityType"> The entity type to set the containing property name for. </param>
/// <param name="name"> The name to set. </param>
/// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param>
public static void SetCosmosContainingPropertyName(
[NotNull] this IConventionEntityType entityType, [CanBeNull] string name, bool fromDataAnnotation = false)
=> entityType.SetOrRemoveAnnotation(
CosmosAnnotationNames.PropertyName,
Check.NullButNotEmpty(name, nameof(name)),
fromDataAnnotation);

/// <summary>
/// Gets the <see cref="ConfigurationSource" /> for the parent property to which the entity type is mapped.
/// </summary>
/// <param name="entityType"> The entity type to find configuration source for. </param>
/// <returns> The <see cref="ConfigurationSource" /> for the parent property to which the entity type is mapped. </returns>
public static ConfigurationSource? GetCosmosContainingPropertyNameConfigurationSource([NotNull] this IConventionEntityType entityType)
=> entityType.FindAnnotation(CosmosAnnotationNames.PropertyName)
?.GetConfigurationSource();
}
}
62 changes: 0 additions & 62 deletions src/EFCore.Cosmos/Extensions/CosmosMetadataExtensions.cs

This file was deleted.

Loading

0 comments on commit d4b0d9d

Please sign in to comment.