Update MongoDB provider with support for non-Id key fields

This commit is contained in:
Sipke Schoorstra 2023-08-04 23:05:37 +02:00
parent e2cea7310f
commit 68c0ad0bff
10 changed files with 25 additions and 13 deletions

View file

@ -1,4 +1,5 @@
using System.Linq.Expressions;
using Elsa.Extensions;
using Elsa.MongoDb.Extensions;
using JetBrains.Annotations;
using MongoDB.Driver;
@ -163,12 +164,21 @@ public class MongoDbStore<TDocument> where TDocument : class
/// Deletes documents using a query.
/// </summary>
/// <returns>The number of documents deleted.</returns>
public async Task<long> DeleteWhereAsync(Func<IMongoQueryable<TDocument>, IMongoQueryable<TDocument>> query, CancellationToken cancellationToken = default)
public async Task<long> DeleteWhereAsync<TKey>(Func<IMongoQueryable<TDocument>, IMongoQueryable<TDocument>> query, Expression<Func<TDocument, TKey>> keySelector, CancellationToken cancellationToken = default)
{
var key = keySelector.GetPropertyName();
return await DeleteWhereAsync(query, key, cancellationToken);
}
/// <summary>
/// Deletes documents using a query.
/// </summary>
/// <returns>The number of documents deleted.</returns>
public async Task<long> DeleteWhereAsync(Func<IMongoQueryable<TDocument>, IMongoQueryable<TDocument>> query, string key = "Id", CancellationToken cancellationToken = default)
{
var documentsToDelete = await query(_collection.AsQueryable()).ToListAsync(cancellationToken);
var count = documentsToDelete.LongCount();
var filter = documentsToDelete.BuildIdFilterForList();
var filter = documentsToDelete.BuildIdFilterForList(key);
await _collection.DeleteManyAsync(filter, cancellationToken);
return count;

View file

@ -42,11 +42,12 @@ public static class DocumentExtensions
/// Builds a filter expression for the Id property name of the specified documents.
/// </summary>
/// <param name="documents">The documents.</param>
/// <param name="key">The key.</param>
/// <typeparam name="TDocument">The type of the document.</typeparam>
/// <exception cref="InvalidOperationException">The type does not have an Id property.</exception>
public static FilterDefinition<TDocument> BuildIdFilterForList<TDocument>(this IEnumerable<TDocument> documents)
public static FilterDefinition<TDocument> BuildIdFilterForList<TDocument>(this IEnumerable<TDocument> documents, string key = "Id")
{
var propertyName = "Id";
var propertyName = key;
var idProperty = typeof(TDocument).GetProperty(propertyName);
if (idProperty == null)
{

View file

@ -27,7 +27,7 @@ public class MongoApplicationStore : IApplicationStore
/// <inheritdoc />
public async Task DeleteAsync(ApplicationFilter filter, CancellationToken cancellationToken = default) =>
await _applicationMongoDbStore.DeleteWhereAsync(query => Filter(query, filter), cancellationToken);
await _applicationMongoDbStore.DeleteWhereAsync<string>(query => Filter(query, filter), x => x.Id, cancellationToken);
/// <inheritdoc />
public async Task<Application?> FindAsync(ApplicationFilter filter, CancellationToken cancellationToken = default) =>

View file

@ -25,12 +25,13 @@ public class MongoRoleStore : IRoleStore
public async Task SaveAsync(Role application, CancellationToken cancellationToken = default) =>
await _roleMongoDbStore.SaveAsync(application, cancellationToken);
/// <inheritdoc />
public async Task AddAsync(Role role, CancellationToken cancellationToken = default) =>
await _roleMongoDbStore.SaveAsync(role, cancellationToken);
/// <inheritdoc />
public async Task DeleteAsync(RoleFilter filter, CancellationToken cancellationToken = default) =>
await _roleMongoDbStore.DeleteWhereAsync(query => Filter(query, filter), cancellationToken);
await _roleMongoDbStore.DeleteWhereAsync<string>(query => Filter(query, filter), x => x.Id, cancellationToken);
/// <inheritdoc />
public async Task<Role?> FindAsync(RoleFilter filter, CancellationToken cancellationToken = default) =>

View file

@ -27,7 +27,7 @@ public class MongoUserStore : IUserStore
/// <inheritdoc />
public async Task DeleteAsync(UserFilter filter, CancellationToken cancellationToken = default) =>
await _userMongoDbStore.DeleteWhereAsync(query => Filter(query, filter), cancellationToken);
await _userMongoDbStore.DeleteWhereAsync<string>(query => Filter(query, filter), x => x.Id, cancellationToken);
/// <inheritdoc />
public async Task<User?> FindAsync(UserFilter filter, CancellationToken cancellationToken = default) =>

View file

@ -85,7 +85,7 @@ public class MongoWorkflowInstanceStore : IWorkflowInstanceStore
/// <inheritdoc />
public async Task<long> DeleteAsync(WorkflowInstanceFilter filter, CancellationToken cancellationToken = default) =>
await _mongoDbStore.DeleteWhereAsync(query => Filter(query, filter), cancellationToken);
await _mongoDbStore.DeleteWhereAsync<string>(query => Filter(query, filter), x => x.Id, cancellationToken);
/// <inheritdoc />
public async Task SaveAsync(WorkflowInstance instance, CancellationToken cancellationToken = default) =>

View file

@ -31,7 +31,7 @@ public class MongoBookmarkStore : IBookmarkStore
/// <inheritdoc />
public async ValueTask<long> DeleteAsync(BookmarkFilter filter, CancellationToken cancellationToken = default) =>
await _mongoDbStore.DeleteWhereAsync(query => Filter(query, filter), cancellationToken);
await _mongoDbStore.DeleteWhereAsync<string>(query => Filter(query, filter), x => x.BookmarkId, cancellationToken);
private IMongoQueryable<StoredBookmark> Filter(IMongoQueryable<StoredBookmark> queryable, BookmarkFilter filter) =>
(filter.Apply(queryable) as IMongoQueryable<StoredBookmark>)!;

View file

@ -49,7 +49,7 @@ public class MongoTriggerStore : ITriggerStore
/// <inheritdoc />
public async ValueTask<long> DeleteManyAsync(TriggerFilter filter, CancellationToken cancellationToken = default) =>
await _mongoDbStore.DeleteWhereAsync(query => Filter(query, filter), cancellationToken);
await _mongoDbStore.DeleteWhereAsync<string>(query => Filter(query, filter), x => x.Id, cancellationToken);
private static IMongoQueryable<StoredTrigger> Filter(IMongoQueryable<StoredTrigger> queryable, TriggerFilter filter) =>
(filter.Apply(queryable) as IMongoQueryable<StoredTrigger>)!;

View file

@ -66,7 +66,7 @@ public class MongoWorkflowExecutionLogStore : IWorkflowExecutionLogStore
/// <inheritdoc />
public async Task<long> DeleteManyAsync(WorkflowExecutionLogRecordFilter filter, CancellationToken cancellationToken = default)
{
return await _mongoDbStore.DeleteWhereAsync(queryable => Filter(queryable, filter), cancellationToken);
return await _mongoDbStore.DeleteWhereAsync<string>(queryable => Filter(queryable, filter), x => x.Id, cancellationToken);
}
private IMongoQueryable<WorkflowExecutionLogRecord> Filter(IMongoQueryable<WorkflowExecutionLogRecord> queryable, WorkflowExecutionLogRecordFilter filter) =>

View file

@ -52,7 +52,7 @@ public class MongoWorkflowStateStore : IWorkflowStateStore
/// <inheritdoc />
public async Task<long> DeleteManyAsync(WorkflowStateFilter filter, CancellationToken cancellationToken = default)
{
return await _mongoDbStore.DeleteWhereAsync(queryable => Filter(queryable, filter), cancellationToken);
return await _mongoDbStore.DeleteWhereAsync<string>(queryable => Filter(queryable, filter), x => x.Id, cancellationToken);
}
private IMongoQueryable<WorkflowState> Filter(IMongoQueryable<WorkflowState> queryable, WorkflowStateFilter filter) => (filter.Apply(queryable) as IMongoQueryable<WorkflowState>)!;