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;
}
}