generated from Avanade/avanade-template
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- *Fixed:* `CosmosDbValue<TModel>.PrepareBefore` corrected to set the `PartitionKey` where the underlying `Value` implements `IPartitionKey`. - *Fixed:* `CosmosDbBatch` corrected to default to the `CosmosDbContainerBase<TSelf>.DbArgs` where not specified. - *Fixed:* `CosmosDbArgs.AutoMapETag` added, indicates whether when mapping the model to the corresponding entity that the `IETag.ETag` is to be automatically mapped (default is `true`, existing behavior).
- Loading branch information
Showing
13 changed files
with
198 additions
and
211 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,119 +1,43 @@ | ||
// Copyright (c) Avanade. Licensed under the MIT License. See https://github.com/Avanade/CoreEx | ||
|
||
using CoreEx.Abstractions; | ||
using CoreEx.Cosmos.Model; | ||
using CoreEx.Entities; | ||
using CoreEx.Mapping; | ||
using CoreEx.Results; | ||
using Microsoft.Azure.Cosmos; | ||
using System; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace CoreEx.Cosmos | ||
{ | ||
/// <summary> | ||
/// Provides <see cref="Container"/> operations for a <see cref="CosmosDb"/> container. | ||
/// Provides the core <see cref="Container"/> capabilities. | ||
/// </summary> | ||
/// <typeparam name="T">The entity <see cref="Type"/>.</typeparam> | ||
/// <typeparam name="TModel">The cosmos model <see cref="Type"/>.</typeparam> | ||
public class CosmosDbContainer<T, TModel> : CosmosDbContainerBase<T, TModel, CosmosDbContainer<T, TModel>> where T : class, IEntityKey, new() where TModel : class, IEntityKey, new() | ||
/// <param name="cosmosDb">The <see cref="ICosmosDb"/>.</param> | ||
/// <param name="containerId">The <see cref="Microsoft.Azure.Cosmos.Container"/> identifier.</param> | ||
/// <param name="dbArgs">The optional <see cref="CosmosDbArgs"/>.</param> | ||
public class CosmosDbContainer(ICosmosDb cosmosDb, string containerId, CosmosDbArgs? dbArgs = null) : ICosmosDbContainer | ||
{ | ||
private readonly Lazy<CosmosDbModelContainer<TModel>> _modelContainer; | ||
private CosmosDbArgs? _dbArgs = dbArgs; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="CosmosDbContainer{T, TModel}"/> class. | ||
/// </summary> | ||
/// <param name="cosmosDb">The <see cref="ICosmosDb"/>.</param> | ||
/// <param name="containerId">The <see cref="Microsoft.Azure.Cosmos.Container"/> identifier.</param> | ||
/// <param name="dbArgs">The optional <see cref="CosmosDbArgs"/>.</param> | ||
public CosmosDbContainer(ICosmosDb cosmosDb, string containerId, CosmosDbArgs? dbArgs = null) : base(cosmosDb, containerId, dbArgs) | ||
=> _modelContainer = new(() => new CosmosDbModelContainer<TModel>(CosmosDb, Container.Id, DbArgs)); | ||
|
||
/// <summary> | ||
/// Gets the underlying <see cref="CosmosDbModelContainer{TModel}"/>. | ||
/// </summary> | ||
public CosmosDbModelContainer<TModel> ModelContainer => _modelContainer.Value; | ||
/// <inheritdoc/> | ||
public ICosmosDb CosmosDb { get; } = cosmosDb.ThrowIfNull(nameof(cosmosDb)); | ||
|
||
/// <summary> | ||
/// Sets the function to determine the <see cref="PartitionKey"/>; used for <see cref="CosmosDbModelContainer{TModel}.GetPartitionKey(TModel, CosmosDbArgs)"/> (only <b>Create</b> and <b>Update</b> operations). | ||
/// </summary> | ||
/// <param name="partitionKey">The function to determine the <see cref="PartitionKey"/>.</param> | ||
/// <returns>The <see cref="CosmosDbContainer{T, TModel}"/> instance to support fluent-style method-chaining.</returns> | ||
/// <remarks>This is used where there is a value and the corresponding <see cref="PartitionKey"/> needs to be dynamically determined.</remarks> | ||
public CosmosDbContainer<T, TModel> UsePartitionKey(Func<TModel, PartitionKey> partitionKey) | ||
{ | ||
ModelContainer.UsePartitionKey(partitionKey); | ||
return this; | ||
} | ||
/// <inheritdoc/> | ||
public Container Container { get; } = cosmosDb.GetCosmosContainer(containerId); | ||
|
||
/// <summary> | ||
/// Gets the <b>value</b> formatting/updating any special properties as required. | ||
/// Gets or sets the Container-specific <see cref="CosmosDbArgs"/>. | ||
/// </summary> | ||
/// <param>The model value.</param> | ||
/// <returns>The entity value.</returns> | ||
[return: NotNullIfNotNull(nameof(model))] | ||
public T? GetValue(TModel? model) | ||
/// <remarks>Defaults to <see cref="ICosmosDb.DbArgs"/> on first access.</remarks> | ||
public CosmosDbArgs DbArgs | ||
{ | ||
var val = CosmosDb.Mapper.Map<TModel, T>(model, OperationTypes.Get)!; | ||
if (val is IETag et && et.ETag != null) | ||
et.ETag = ETagGenerator.ParseETag(et.ETag); | ||
|
||
return DbArgs.CleanUpResult ? Cleaner.Clean(val) : val; | ||
get => _dbArgs ??= new CosmosDbArgs(CosmosDb.DbArgs); | ||
set => _dbArgs = value; | ||
} | ||
|
||
/// <summary> | ||
/// Gets (creates) a <see cref="CosmosDbQuery{T, TModel}"/> to enable LINQ-style queries. | ||
/// </summary> | ||
/// <param name="query">The function to perform additional query execution.</param> | ||
/// <returns>The <see cref="CosmosDbQuery{T, TModel}"/>.</returns> | ||
public CosmosDbQuery<T, TModel> Query(Func<IQueryable<TModel>, IQueryable<TModel>>? query) => Query(new CosmosDbArgs(DbArgs), query); | ||
|
||
/// <summary> | ||
/// Gets (creates) a <see cref="CosmosDbQuery{T, TModel}"/> to enable LINQ-style queries. | ||
/// Gets the <b>CosmosDb</b> identifier from the <see cref="CompositeKey"/>. | ||
/// </summary> | ||
/// <param name="partitionKey">The <see cref="PartitionKey"/>.</param> | ||
/// <param name="query">The function to perform additional query execution.</param> | ||
/// <returns>The <see cref="CosmosDbQuery{T, TModel}"/>.</returns> | ||
public CosmosDbQuery<T, TModel> Query(PartitionKey? partitionKey = null, Func<IQueryable<TModel>, IQueryable<TModel>>? query = null) => Query(new CosmosDbArgs(DbArgs, partitionKey), query); | ||
|
||
/// <summary> | ||
/// Gets (creates) a <see cref="CosmosDbQuery{T, TModel}"/> to enable LINQ-style queries. | ||
/// </summary> | ||
/// <param name="dbArgs">The <see cref="CosmosDbArgs"/>.</param> | ||
/// <param name="query">The function to perform additional query execution.</param> | ||
/// <returns>The <see cref="CosmosDbQuery{T, TModel}"/>.</returns> | ||
public CosmosDbQuery<T, TModel> Query(CosmosDbArgs dbArgs, Func<IQueryable<TModel>, IQueryable<TModel>>? query = null) => new(this, dbArgs, query); | ||
|
||
/// <inheritdoc/> | ||
public async override Task<Result<T?>> GetWithResultAsync(CosmosDbArgs dbArgs, CompositeKey key, CancellationToken cancellationToken = default) | ||
{ | ||
var result = await ModelContainer.GetWithResultAsync(dbArgs, key, cancellationToken).ConfigureAwait(false); | ||
return result.ThenAs(GetValue); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override async Task<Result<T>> CreateWithResultAsync(CosmosDbArgs dbArgs, T value, CancellationToken cancellationToken = default) | ||
{ | ||
ChangeLog.PrepareCreated(value.ThrowIfNull(nameof(value))); | ||
TModel model = CosmosDb.Mapper.Map<T, TModel>(value, OperationTypes.Create)!; | ||
|
||
var result = await ModelContainer.CreateWithResultAsync(dbArgs, model, cancellationToken).ConfigureAwait(false); | ||
return result.ThenAs(model => GetValue(model)!); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override async Task<Result<T>> UpdateWithResultAsync(CosmosDbArgs dbArgs, T value, CancellationToken cancellationToken = default) | ||
{ | ||
ChangeLog.PrepareUpdated(value); | ||
var model = CosmosDb.Mapper.Map<T, TModel>(value.ThrowIfNull(nameof(value)), OperationTypes.Update)!; | ||
var result = await ModelContainer.UpdateWithResultInternalAsync(dbArgs, model, m => CosmosDb.Mapper.Map(value, m, OperationTypes.Update), cancellationToken).ConfigureAwait(false); | ||
return result.ThenAs(model => GetValue(model)!); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override Task<Result> DeleteWithResultAsync(CosmosDbArgs dbArgs, CompositeKey key, CancellationToken cancellationToken = default) => ModelContainer.DeleteWithResultAsync(dbArgs, key, cancellationToken); | ||
/// <param name="key">The <see cref="CompositeKey"/>.</param> | ||
/// <returns>The <b>CosmosDb</b> identifier.</returns> | ||
/// <remarks>Uses the <see cref="CosmosDbArgs.FormatIdentifier"/> to format the <paramref name="key"/> as a string (as required).</remarks> | ||
public virtual string GetCosmosId(CompositeKey key) => DbArgs.FormatIdentifier(key) ?? throw new InvalidOperationException("The CompositeKey formatting must not result in a null."); | ||
} | ||
} |
Oops, something went wrong.