Incremental fix for YesSQL provider with And/Or specifications
Fixes #1472
This commit is contained in:
parent
b007dc7574
commit
de9ac4b074
|
|
@ -4,18 +4,18 @@ using LinqKit;
|
|||
|
||||
namespace Elsa.Persistence.Specifications
|
||||
{
|
||||
internal struct AndSpecification<T> : ISpecification<T>
|
||||
public struct AndSpecification<T> : ISpecification<T>
|
||||
{
|
||||
private readonly ISpecification<T> _left;
|
||||
private readonly ISpecification<T> _right;
|
||||
|
||||
public AndSpecification(ISpecification<T> left, ISpecification<T> right)
|
||||
{
|
||||
_right = right;
|
||||
_left = left;
|
||||
Right = right;
|
||||
Left = left;
|
||||
}
|
||||
|
||||
public bool IsSatisfiedBy(T entity) => _left.IsSatisfiedBy(entity) && _right.IsSatisfiedBy(entity);
|
||||
public Expression<Func<T, bool>> ToExpression() => _left.ToExpression().And(_right.ToExpression());
|
||||
public bool IsSatisfiedBy(T entity) => Left.IsSatisfiedBy(entity) && Right.IsSatisfiedBy(entity);
|
||||
public Expression<Func<T, bool>> ToExpression() => Left.ToExpression().And(Right.ToExpression());
|
||||
|
||||
public ISpecification<T> Left { get; }
|
||||
public ISpecification<T> Right { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ using System.Linq.Expressions;
|
|||
|
||||
namespace Elsa.Persistence.Specifications
|
||||
{
|
||||
internal struct NotSpecification<T> : ISpecification<T>
|
||||
public struct NotSpecification<T> : ISpecification<T>
|
||||
{
|
||||
private readonly ISpecification<T> _specification;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using LinqKit;
|
|||
|
||||
namespace Elsa.Persistence.Specifications
|
||||
{
|
||||
internal struct OrSpecification<T> : ISpecification<T>
|
||||
public struct OrSpecification<T> : ISpecification<T>
|
||||
{
|
||||
private readonly ISpecification<T> _left;
|
||||
private readonly ISpecification<T> _right;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AutoMapper;
|
||||
|
|
@ -40,6 +41,7 @@ namespace Elsa.Persistence.YesSql.Stores
|
|||
: Query<WorkflowDefinitionIndex>(session, x => x.DefinitionId.IsIn(s.Ids)).WithVersion(s.VersionOptions),
|
||||
|
||||
WorkflowDefinitionVersionIdSpecification s => Query<WorkflowDefinitionIndex>(session, x => x.DefinitionVersionId == s.VersionId),
|
||||
AndSpecification<WorkflowDefinition> s => MapAndSpecification(session, s),
|
||||
VersionOptionsSpecification s => Query<WorkflowDefinitionIndex>(session).WithVersion(s.VersionOptions),
|
||||
_ => AutoMapSpecification<WorkflowDefinitionIndex>(session, specification)
|
||||
};
|
||||
|
|
@ -51,5 +53,32 @@ namespace Elsa.Persistence.YesSql.Stores
|
|||
var indexedQuery = query.With<WorkflowDefinitionIndex>();
|
||||
return orderBy.SortDirection == SortDirection.Ascending ? indexedQuery.OrderBy(expression) : indexedQuery.OrderByDescending(expression);
|
||||
}
|
||||
|
||||
/// TODO: This is a workaround. The real fix might be to remove the specification pattern and replace with repository abstractions with finite methods, or automatically dig into And and Or specifications and map each branch into a YesSQL queryable predicate.
|
||||
private IQuery<WorkflowDefinitionDocument> MapAndSpecification(ISession session, AndSpecification<WorkflowDefinition> and)
|
||||
{
|
||||
var left = and.Left;
|
||||
var right = and.Right;
|
||||
|
||||
if(left is ManyWorkflowDefinitionIdsSpecification manyWorkflowDefinitionIdsSpecification && right is TenantSpecification<WorkflowDefinition> tenantSpecification)
|
||||
{
|
||||
return CreateQuery(session, manyWorkflowDefinitionIdsSpecification.Ids, manyWorkflowDefinitionIdsSpecification.VersionOptions, tenantSpecification.TenantId);
|
||||
}
|
||||
|
||||
return AutoMapSpecification<WorkflowDefinitionIndex>(session, and);
|
||||
}
|
||||
|
||||
private IQuery<WorkflowDefinitionDocument> CreateQuery(ISession session, IEnumerable<string> definitionIds, VersionOptions? versionOptions = default, string? tenantId = default)
|
||||
{
|
||||
var query = Query<WorkflowDefinitionIndex>(session).Where(x => x.DefinitionId.IsIn(definitionIds));
|
||||
|
||||
if (versionOptions != null)
|
||||
query.WithVersion(versionOptions);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(tenantId))
|
||||
query.Where(x => x.TenantId == tenantId);
|
||||
|
||||
return query;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue