using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace TEAMModelOS.SDK.Module.AzureCosmosDBV3
{
///
//
/*
Expression> exp = x => x.Status == (int)BizConst.UserStatus.Active;
if(parameters.IsAuthenticated)
{
exp = exp.And(x => x.IdentityAuth == (int) BizConst.IdentityAuthStatus.Authed && x.CareerAuth == (int) BizConst.GlobalCareerStatus.Authed);
}
if(parameters.IsVip)
{
exp = exp.And(x => x.Vip != (int) BizConst.VipTag.NoVip);
}*/
///
public static class PredicateExtensions
{
/////
///// 机关函数应用True时:单个AND有效,多个AND有效;单个OR无效,多个OR无效;混应时写在AND后的OR有效。即,设置为True时所有or语句应该放在and语句之后,否则无效
/////
//public static Expression> True() { return f => true; }
/////
///// 机关函数应用False时:单个AND无效,多个AND无效;单个OR有效,多个OR有效;混应时写在OR后面的AND有效。 即,设置为False时所有or语句应该放在and语句之前,否则无效
/////
//public static Expression> False() { return f => false; }
//public static Expression> Or(this Expression> expression1,
// Expression> expression2)
//{
// var invokedExpression = Expression.Invoke(expression2, expression1.Parameters
// .Cast());
// return Expression.Lambda>(Expression.Or(expression1.Body, invokedExpression),
// expression1.Parameters);
//}
//public static Expression> And(this Expression> expression1,
// Expression> expression2)
//{
// var invokedExpression = Expression.Invoke(expression2, expression1.Parameters
// .Cast());
// return Expression.Lambda>(Expression.And(expression1.Body,
// invokedExpression), expression1.Parameters);
//}
///
/// 机关函数应用True时:单个AND有效,多个AND有效;单个OR无效,多个OR无效;混应时写在AND后的OR有效。即,设置为True时所有or语句应该放在and语句之后,否则无效
///
public static Expression> BaseAnd() { return f => true; }
///
/// 机关函数应用False时:单个AND无效,多个AND无效;单个OR有效,多个OR有效;混应时写在OR后面的AND有效。 即,设置为False时所有or语句应该放在and语句之前,否则无效
///
public static Expression> BaseOr() { return f => false; }
public static Expression> Or(
this Expression> expr1,
Expression> expr2)
{
var secondBody = expr2.Body.Replace(expr2.Parameters[0], expr1.Parameters[0]);
return Expression.Lambda>
(Expression.OrElse(expr1.Body, secondBody), expr1.Parameters);
}
public static Expression> And(
this Expression> expr1,
Expression> expr2)
{
var secondBody = expr2.Body.Replace(expr2.Parameters[0], expr1.Parameters[0]);
return Expression.Lambda>
(Expression.AndAlso(expr1.Body, secondBody), expr1.Parameters);
}
public static Expression Replace(this Expression expression,
Expression searchEx, Expression replaceEx)
{
return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
public static Expression> CombineOrPreicatesWithAndPredicates(this Expression> combinedPredicate,
Expression> andPredicate, Expression> orPredicate)
{
combinedPredicate = combinedPredicate ?? BaseAnd();
if (andPredicate != null && orPredicate != null)
{
andPredicate = andPredicate.And(orPredicate);
combinedPredicate = combinedPredicate.And(andPredicate);
}
else if (orPredicate != null)
{
combinedPredicate = combinedPredicate.And(orPredicate);
}
else
{
combinedPredicate = combinedPredicate.And(andPredicate);
}
return combinedPredicate;
}
public static void AddToPredicateTypeBasedOnIfAndOrOr(ref Expression> andPredicate,
ref Expression> orPredicate, Expression> newExpression, bool isAnd)
{
if (isAnd)
{
andPredicate = andPredicate ?? BaseAnd();
andPredicate = andPredicate.And(newExpression);
}
else
{
orPredicate = orPredicate ?? BaseOr();
orPredicate = orPredicate.Or(newExpression);
}
}
}
internal class ReplaceVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public ReplaceVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
}