Skip to content

Commit b8ad5cc

Browse files
committed
Cosmos: Add API to configure the container that a hierarchy is mapped to, as well as the default container name
Enable materializing derived types polymorphically Add exceptions for some unsupported cases
1 parent 31e0e41 commit b8ad5cc

File tree

55 files changed

+1609
-184
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1609
-184
lines changed

src/EFCore.Abstractions/EFCore.Abstractions.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
<ItemGroup>
2424
<None Update="Properties\AbstractionsStrings.Designer.tt">
2525
<Generator>TextTemplatingFileGenerator</Generator>
26-
<CustomToolNamespace>Microsoft.EntityFrameworkCore.Internal</CustomToolNamespace>
2726
<LastGenOutput>AbstractionsStrings.Designer.cs</LastGenOutput>
2827
</None>
2928
</ItemGroup>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using JetBrains.Annotations;
5+
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;
6+
using Microsoft.EntityFrameworkCore.Infrastructure;
7+
using Microsoft.EntityFrameworkCore.Metadata.Builders;
8+
using Microsoft.EntityFrameworkCore.Metadata.Internal;
9+
using Microsoft.EntityFrameworkCore.Utilities;
10+
11+
namespace Microsoft.EntityFrameworkCore.Cosmos
12+
{
13+
/// <summary>
14+
/// Cosmos specific extension methods for <see cref="CollectionOwnershipBuilder" />.
15+
/// </summary>
16+
public static class CosmosCollectionOwnershipBuilderExtensions
17+
{
18+
/// <summary>
19+
/// Configures the container that the entity maps to when targeting Azure Cosmos.
20+
/// </summary>
21+
/// <param name="referenceOwnershipBuilder"> The builder for the entity type being configured. </param>
22+
/// <param name="name"> The name of the container. </param>
23+
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
24+
public static CollectionOwnershipBuilder ToContainer(
25+
[NotNull] this CollectionOwnershipBuilder referenceOwnershipBuilder,
26+
[CanBeNull] string name)
27+
{
28+
Check.NotNull(referenceOwnershipBuilder, nameof(referenceOwnershipBuilder));
29+
Check.NullButNotEmpty(name, nameof(name));
30+
31+
referenceOwnershipBuilder.GetInfrastructure<InternalEntityTypeBuilder>()
32+
.Cosmos(ConfigurationSource.Explicit)
33+
.ToContainer(name);
34+
35+
return referenceOwnershipBuilder;
36+
}
37+
38+
/// <summary>
39+
/// Configures the container that the entity maps to when targeting Azure Cosmos.
40+
/// </summary>
41+
/// <typeparam name="TEntity"> The entity type being configured. </typeparam>
42+
/// <typeparam name="TDependentEntity"> The entity type that this relationship targets. </typeparam>
43+
/// <param name="referenceOwnershipBuilder"> The builder for the entity type being configured. </param>
44+
/// <param name="name"> The name of the container. </param>
45+
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
46+
public static CollectionOwnershipBuilder<TEntity, TDependentEntity> ToContainer<TEntity, TDependentEntity>(
47+
[NotNull] this CollectionOwnershipBuilder<TEntity, TDependentEntity> referenceOwnershipBuilder,
48+
[CanBeNull] string name)
49+
where TEntity : class
50+
where TDependentEntity : class
51+
=> (CollectionOwnershipBuilder<TEntity, TDependentEntity>)ToContainer((CollectionOwnershipBuilder)referenceOwnershipBuilder, name);
52+
}
53+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using JetBrains.Annotations;
5+
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;
6+
using Microsoft.EntityFrameworkCore.Infrastructure;
7+
using Microsoft.EntityFrameworkCore.Metadata.Builders;
8+
using Microsoft.EntityFrameworkCore.Metadata.Internal;
9+
using Microsoft.EntityFrameworkCore.Utilities;
10+
11+
// ReSharper disable once CheckNamespace
12+
namespace Microsoft.EntityFrameworkCore
13+
{
14+
/// <summary>
15+
/// Cosmos specific extension methods for <see cref="EntityTypeBuilder" />.
16+
/// </summary>
17+
public static class CosmosEntityTypeBuilderExtensions
18+
{
19+
/// <summary>
20+
/// Configures the container that the entity maps to when targeting Azure Cosmos.
21+
/// </summary>
22+
/// <param name="entityTypeBuilder"> The builder for the entity type being configured. </param>
23+
/// <param name="name"> The name of the container. </param>
24+
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
25+
public static EntityTypeBuilder ToContainer(
26+
[NotNull] this EntityTypeBuilder entityTypeBuilder,
27+
[CanBeNull] string name)
28+
{
29+
Check.NotNull(entityTypeBuilder, nameof(entityTypeBuilder));
30+
Check.NullButNotEmpty(name, nameof(name));
31+
32+
entityTypeBuilder.GetInfrastructure<InternalEntityTypeBuilder>()
33+
.Cosmos(ConfigurationSource.Explicit)
34+
.ToContainer(name);
35+
36+
return entityTypeBuilder;
37+
}
38+
39+
/// <summary>
40+
/// Configures the container that the entity maps to when targeting Azure Cosmos.
41+
/// </summary>
42+
/// <typeparam name="TEntity"> The entity type being configured. </typeparam>
43+
/// <param name="entityTypeBuilder"> The builder for the entity type being configured. </param>
44+
/// <param name="name"> The name of the container. </param>
45+
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
46+
public static EntityTypeBuilder<TEntity> ToContainer<TEntity>(
47+
[NotNull] this EntityTypeBuilder<TEntity> entityTypeBuilder,
48+
[CanBeNull] string name)
49+
where TEntity : class
50+
=> (EntityTypeBuilder<TEntity>)ToContainer((EntityTypeBuilder)entityTypeBuilder, name);
51+
}
52+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using JetBrains.Annotations;
5+
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;
6+
using Microsoft.EntityFrameworkCore.Infrastructure;
7+
using Microsoft.EntityFrameworkCore.Metadata.Internal;
8+
using Microsoft.EntityFrameworkCore.Utilities;
9+
10+
// ReSharper disable once CheckNamespace
11+
namespace Microsoft.EntityFrameworkCore
12+
{
13+
public static class CosmosModelBuilderExtensions
14+
{
15+
/// <summary>
16+
/// Configures the default container name that will be used if no name
17+
/// is explicitly configured for an entity type.
18+
/// </summary>
19+
/// <param name="modelBuilder"> The model builder. </param>
20+
/// <param name="name"> The default container name. </param>
21+
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
22+
public static ModelBuilder HasDefaultContainerName(
23+
[NotNull] this ModelBuilder modelBuilder,
24+
[CanBeNull] string name)
25+
{
26+
Check.NotNull(modelBuilder, nameof(modelBuilder));
27+
Check.NullButNotEmpty(name, nameof(name));
28+
29+
modelBuilder.GetInfrastructure().Cosmos(ConfigurationSource.Explicit).HasDefaultContainerName(name);
30+
31+
return modelBuilder;
32+
}
33+
}
34+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using JetBrains.Annotations;
5+
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;
6+
using Microsoft.EntityFrameworkCore.Infrastructure;
7+
using Microsoft.EntityFrameworkCore.Metadata.Builders;
8+
using Microsoft.EntityFrameworkCore.Metadata.Internal;
9+
using Microsoft.EntityFrameworkCore.Utilities;
10+
11+
namespace Microsoft.EntityFrameworkCore.Cosmos
12+
{
13+
/// <summary>
14+
/// Cosmos specific extension methods for <see cref="ReferenceOwnershipBuilder" />.
15+
/// </summary>
16+
public static class CosmosReferenceOwnershipBuilderExtensions
17+
{
18+
/// <summary>
19+
/// Configures the container that the entity maps to when targeting Azure Cosmos.
20+
/// </summary>
21+
/// <param name="referenceOwnershipBuilder"> The builder for the entity type being configured. </param>
22+
/// <param name="name"> The name of the container. </param>
23+
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
24+
public static ReferenceOwnershipBuilder ToContainer(
25+
[NotNull] this ReferenceOwnershipBuilder referenceOwnershipBuilder,
26+
[CanBeNull] string name)
27+
{
28+
Check.NotNull(referenceOwnershipBuilder, nameof(referenceOwnershipBuilder));
29+
Check.NullButNotEmpty(name, nameof(name));
30+
31+
referenceOwnershipBuilder.GetInfrastructure<InternalEntityTypeBuilder>()
32+
.Cosmos(ConfigurationSource.Explicit)
33+
.ToContainer(name);
34+
35+
return referenceOwnershipBuilder;
36+
}
37+
38+
/// <summary>
39+
/// Configures the container that the entity maps to when targeting Azure Cosmos.
40+
/// </summary>
41+
/// <typeparam name="TEntity"> The entity type being configured. </typeparam>
42+
/// <typeparam name="TRelatedEntity"> The entity type that this relationship targets. </typeparam>
43+
/// <param name="referenceOwnershipBuilder"> The builder for the entity type being configured. </param>
44+
/// <param name="name"> The name of the container. </param>
45+
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
46+
public static ReferenceOwnershipBuilder<TEntity, TRelatedEntity> ToContainer<TEntity, TRelatedEntity>(
47+
[NotNull] this ReferenceOwnershipBuilder<TEntity, TRelatedEntity> referenceOwnershipBuilder,
48+
[CanBeNull] string name)
49+
where TEntity : class
50+
where TRelatedEntity : class
51+
=> (ReferenceOwnershipBuilder<TEntity, TRelatedEntity>)ToContainer((ReferenceOwnershipBuilder)referenceOwnershipBuilder, name);
52+
}
53+
}

src/EFCore.Cosmos/EFCore.Cosmos.csproj

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,30 @@
2626
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
2727
</ItemGroup>
2828

29+
<ItemGroup>
30+
<Compile Update="Properties\CosmosStrings.Designer.cs">
31+
<DependentUpon>CosmosStrings.Designer.tt</DependentUpon>
32+
<DesignTime>True</DesignTime>
33+
<AutoGen>True</AutoGen>
34+
</Compile>
35+
</ItemGroup>
36+
37+
<ItemGroup>
38+
<None Update="Properties\CosmosStrings.Designer.tt">
39+
<CustomToolNamespace></CustomToolNamespace>
40+
<Generator>TextTemplatingFileGenerator</Generator>
41+
<LastGenOutput>CosmosStrings.Designer.cs</LastGenOutput>
42+
</None>
43+
</ItemGroup>
44+
45+
<ItemGroup>
46+
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
47+
</ItemGroup>
48+
49+
<ItemGroup>
50+
<EmbeddedResource Update="Properties\CosmosStrings.resx">
51+
<CustomToolNamespace>Microsoft.EntityFrameworkCore.Cosmos.Internal</CustomToolNamespace>
52+
</EmbeddedResource>
53+
</ItemGroup>
54+
2955
</Project>

src/EFCore.Cosmos/Extensions/CosmosMetadataExtensions.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@ namespace Microsoft.EntityFrameworkCore
1111
/// </summary>
1212
public static class CosmosMetadataExtensions
1313
{
14+
/// <summary>
15+
/// Gets the Cosmos-specific metadata for a model.
16+
/// </summary>
17+
/// <param name="model"> The model to get metadata for. </param>
18+
/// <returns> The Cosmos-specific metadata for the model. </returns>
19+
public static ICosmosModelAnnotations Cosmos(this IModel model)
20+
=> new CosmosModelAnnotations(model);
21+
22+
/// <summary>
23+
/// Gets the Cosmos-specific metadata for a model.
24+
/// </summary>
25+
/// <param name="model"> The model to get metadata for. </param>
26+
/// <returns> The Cosmos-specific metadata for the model. </returns>
27+
public static CosmosModelAnnotations Cosmos(this IMutableModel model)
28+
=> (CosmosModelAnnotations)Cosmos((IModel)model);
29+
1430
/// <summary>
1531
/// Gets the Cosmos-specific metadata for an entity type.
1632
/// </summary>

src/EFCore.Cosmos/Extensions/CosmosServiceCollectionExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using JetBrains.Annotations;
5+
using Microsoft.EntityFrameworkCore.Cosmos.Infrastructure;
56
using Microsoft.EntityFrameworkCore.Cosmos.Infrastructure.Internal;
67
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions.Internal;
78
using Microsoft.EntityFrameworkCore.Cosmos.Query.ExpressionVisitors.Internal;
@@ -28,14 +29,14 @@ public static IServiceCollection AddEntityFrameworkCosmos([NotNull] this IServic
2829
.TryAdd<IDatabase, CosmosDatabase>()
2930
.TryAdd<IExecutionStrategyFactory, CosmosExecutionStrategyFactory>()
3031
.TryAdd<IDbContextTransactionManager, CosmosTransactionManager>()
32+
.TryAdd<IModelCustomizer, CosmosModelCustomizer>()
3133
.TryAdd<IConventionSetBuilder, CosmosConventionSetBuilder>()
3234
.TryAdd<IDatabaseCreator, CosmosDatabaseCreator>()
3335
.TryAdd<IQueryContextFactory, CosmosQueryContextFactory>()
3436
.TryAdd<IEntityQueryModelVisitorFactory, CosmosEntityQueryModelVisitorFactory>()
3537
.TryAdd<IEntityQueryableExpressionVisitorFactory, CosmosEntityQueryableExpressionVisitorFactory>()
3638
.TryAdd<IMemberAccessBindingExpressionVisitorFactory, CosmosMemberAccessBindingExpressionVisitorFactory>()
3739
.TryAdd<INavigationRewritingExpressionVisitorFactory, CosmosNavigationRewritingExpressionVisitorFactory>()
38-
.TryAdd<IEagerLoadingExpressionVisitorFactory, CosmosEagerLoadingExpressionVisitorFactory>()
3940
.TryAddProviderSpecificServices(
4041
b => b
4142
.TryAddScoped<CosmosClient, CosmosClient>()
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal;
5+
using Microsoft.EntityFrameworkCore.Infrastructure;
6+
using Microsoft.EntityFrameworkCore.Metadata.Internal;
7+
8+
namespace Microsoft.EntityFrameworkCore.Cosmos.Infrastructure
9+
{
10+
/// <summary>
11+
/// <para>
12+
/// Builds the model for a given context. This default implementation builds the model by calling
13+
/// <see cref="DbContext.OnConfiguring(DbContextOptionsBuilder)" /> on the context.
14+
/// </para>
15+
/// <para>
16+
/// This type is typically used by database providers (and other extensions). It is generally
17+
/// not used in application code.
18+
/// </para>
19+
/// </summary>
20+
public class CosmosModelCustomizer : ModelCustomizer
21+
{
22+
public CosmosModelCustomizer(ModelCustomizerDependencies dependencies)
23+
: base(dependencies)
24+
{
25+
}
26+
27+
/// <summary>
28+
/// <para>
29+
/// Performs additional configuration of the model in addition to what is discovered by convention. This implementation
30+
/// builds the model for a given context by calling <see cref="DbContext.OnConfiguring(DbContextOptionsBuilder)" />
31+
/// on the context.
32+
/// </para>
33+
/// </summary>
34+
/// <param name="modelBuilder">
35+
/// The builder being used to construct the model.
36+
/// </param>
37+
/// <param name="context">
38+
/// The context instance that the model is being created for.
39+
/// </param>
40+
public override void Customize(ModelBuilder modelBuilder, DbContext context)
41+
{
42+
modelBuilder.GetInfrastructure().Cosmos(ConfigurationSource.Convention).HasDefaultContainerName(context.GetType().Name);
43+
44+
base.Customize(modelBuilder, context);
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)