using System.Linq.Expressions; using Elsa.Extensions; // ReSharper disable once CheckNamespace namespace Elsa.Persistence.EFCore.Extensions; /// /// Provides extension methods for objects. /// public static class ExpressionExtensions { /// /// Builds an expression that checks if the specified property is contained in the specified list of entities. /// /// The key selector. /// The entities. /// The type of the entity. /// The expression. public static Expression> BuildContainsExpression(this Expression> keySelector, IEnumerable entities) where TEntity : class { var compiledKeySelector = keySelector.Compile(); var list = entities.Select(compiledKeySelector).ToList(); var property = keySelector.GetProperty()!; var param = Expression.Parameter(typeof(TEntity)); var body = Expression.Call( typeof(Enumerable), "Contains", new[] {compiledKeySelector.Method.ReturnType}, Expression.Constant(list), Expression.Property(param, property)); return Expression.Lambda>(body, param); } /// /// Builds an expression that checks if the specified property is equal to the specified entity's property. /// /// The key selector. /// The entity. /// The type of the entity. /// The expression. public static Expression> BuildEqualsExpression(this Expression> keySelector, TEntity entity) { var keyName = keySelector.GetProperty()!.Name; // Define parameters for the lambda expression var parameter = Expression.Parameter(typeof(TEntity), "x"); var keySelectorLambda = Expression.Lambda>(Expression.Property(parameter, keyName), parameter); // Build the expression that compares the keys var entityKey = keySelectorLambda.Compile()(entity); var comparison = Expression.Equal(keySelectorLambda.Body, Expression.Constant(entityKey)); // Create the final lambda expression that can be used in AnyAsync var lambda = Expression.Lambda>(comparison, parameter); return lambda; } }