You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
7.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace zzz.Common.Helper
{
public static class ExpressionExtensions
{
/// <summary>
/// 组合两个表达式
/// </summary>
/// <typeparam name="TSource">泛型类型</typeparam>
/// <param name="expression">表达式1</param>
/// <param name="extendExpression">表达式2</param>
/// <param name="mergeWay">组合方式</param>
/// <returns>新的表达式</returns>
public static Expression<TSource> Compose<TSource>(this Expression<TSource> expression, Expression<TSource> extendExpression, Func<Expression, Expression, Expression> mergeWay)
{
var parameterExpressionSetter = expression.Parameters
.Select((u, i) => new { u, Parameter = extendExpression.Parameters[i] })
.ToDictionary(d => d.Parameter, d => d.u);
var extendExpressionBody = ParameterReplaceExpressionVisitor.ReplaceParameters(parameterExpressionSetter, extendExpression.Body);
return Expression.Lambda<TSource>(mergeWay(expression.Body, extendExpressionBody), expression.Parameters);
}
/// <summary>
/// 与操作合并两个表达式
/// </summary>
/// <typeparam name="TSource">泛型类型</typeparam>
/// <param name="expression">表达式1</param>
/// <param name="extendExpression">表达式2</param>
/// <returns>新的表达式</returns>
public static Expression<Func<TSource, bool>> And<TSource>(this Expression<Func<TSource, bool>> expression, Expression<Func<TSource, bool>> extendExpression)
{
return expression.Compose(extendExpression, Expression.AndAlso);
}
/// <summary>
/// 与操作合并两个表达式,支持索引器
/// </summary>
/// <typeparam name="TSource">泛型类型</typeparam>
/// <param name="expression">表达式1</param>
/// <param name="extendExpression">表达式2</param>
/// <returns>新的表达式</returns>
public static Expression<Func<TSource, int, bool>> And<TSource>(this Expression<Func<TSource, int, bool>> expression, Expression<Func<TSource, int, bool>> extendExpression)
{
return expression.Compose(extendExpression, Expression.AndAlso);
}
/// <summary>
/// 根据条件成立再与操作合并两个表达式
/// </summary>
/// <typeparam name="TSource">泛型类型</typeparam>
/// <param name="expression">表达式1</param>
/// <param name="condition">布尔条件</param>
/// <param name="extendExpression">表达式2</param>
/// <returns>新的表达式</returns>
public static Expression<Func<TSource, bool>> AndIf<TSource>(this Expression<Func<TSource, bool>> expression, bool condition, Expression<Func<TSource, bool>> extendExpression)
{
return condition ? expression.Compose(extendExpression, Expression.AndAlso) : expression;
}
/// <summary>
/// 根据条件成立再与操作合并两个表达式,支持索引器
/// </summary>
/// <typeparam name="TSource">泛型类型</typeparam>
/// <param name="expression">表达式1</param>
/// <param name="condition">布尔条件</param>
/// <param name="extendExpression">表达式2</param>
/// <returns>新的表达式</returns>
public static Expression<Func<TSource, int, bool>> AndIf<TSource>(this Expression<Func<TSource, int, bool>> expression, bool condition, Expression<Func<TSource, int, bool>> extendExpression)
{
return condition ? expression.Compose(extendExpression, Expression.AndAlso) : expression;
}
/// <summary>
/// 或操作合并两个表达式
/// </summary>
/// <typeparam name="TSource">泛型类型</typeparam>
/// <param name="expression">表达式1</param>
/// <param name="extendExpression">表达式2</param>
/// <returns>新的表达式</returns>
public static Expression<Func<TSource, bool>> Or<TSource>(this Expression<Func<TSource, bool>> expression, Expression<Func<TSource, bool>> extendExpression)
{
return expression.Compose(extendExpression, Expression.OrElse);
}
/// <summary>
/// 或操作合并两个表达式,支持索引器
/// </summary>
/// <typeparam name="TSource">泛型类型</typeparam>
/// <param name="expression">表达式1</param>
/// <param name="extendExpression">表达式2</param>
/// <returns>新的表达式</returns>
public static Expression<Func<TSource, int, bool>> Or<TSource>(this Expression<Func<TSource, int, bool>> expression, Expression<Func<TSource, int, bool>> extendExpression)
{
return expression.Compose(extendExpression, Expression.OrElse);
}
/// <summary>
/// 根据条件成立再或操作合并两个表达式
/// </summary>
/// <typeparam name="TSource">泛型类型</typeparam>
/// <param name="expression">表达式1</param>
/// <param name="condition">布尔条件</param>
/// <param name="extendExpression">表达式2</param>
/// <returns>新的表达式</returns>
public static Expression<Func<TSource, bool>> OrIf<TSource>(this Expression<Func<TSource, bool>> expression, bool condition, Expression<Func<TSource, bool>> extendExpression)
{
return condition ? expression.Compose(extendExpression, Expression.OrElse) : expression;
}
/// <summary>
/// 根据条件成立再或操作合并两个表达式,支持索引器
/// </summary>
/// <typeparam name="TSource">泛型类型</typeparam>
/// <param name="expression">表达式1</param>
/// <param name="condition">布尔条件</param>
/// <param name="extendExpression">表达式2</param>
/// <returns>新的表达式</returns>
public static Expression<Func<TSource, int, bool>> OrIf<TSource>(this Expression<Func<TSource, int, bool>> expression, bool condition, Expression<Func<TSource, int, bool>> extendExpression)
{
return condition ? expression.Compose(extendExpression, Expression.OrElse) : expression;
}
/// <summary>
/// 获取Lambda表达式属性名只限 u=>u.Property 表达式
/// </summary>
/// <typeparam name="TSource">泛型类型</typeparam>
/// <param name="expression">表达式</param>
/// <returns>属性名</returns>
public static string GetExpressionPropertyName<TSource>(this Expression<Func<TSource, object>> expression)
{
if (expression.Body is UnaryExpression unaryExpression)
{
return ((MemberExpression)unaryExpression.Operand).Member.Name;
}
else if (expression.Body is MemberExpression memberExpression)
{
return memberExpression.Member.Name;
}
else if (expression.Body is ParameterExpression parameterExpression)
{
return parameterExpression.Type.Name;
}
throw new InvalidCastException(nameof(expression));
}
/// <summary>
/// 是否是空集合
/// </summary>
/// <typeparam name="TSource">泛型类型</typeparam>
/// <param name="sources">集合对象</param>
/// <returns>是否为空集合</returns>
public static bool IsNullOrEmpty<TSource>(this IEnumerable<TSource> sources)
{
return sources == null || !sources.Any();
}
}
}