基础类
public class ConditionExpression
{
public ConditionExpression()
{
}
public ConditionExpression(ConditionExpression left, ConditionExpression right, string op)
{
this.Left = left;
this.Right = right;
this.Op = op;
}
private ConditionExpression _left;
public ConditionExpression Left
{
get
{
return _left;
}
set
{
if (value.isbottom)
{
value.isfield = true;
}
_left = value;
}
}
public ConditionExpression Right { get; set; }
public string Op { get; set; }
private bool isfield = false;
private bool isbottom = false;
private object _value;
public object Value
{
get { return _value; }
set { _value = value; }
}
public override string ToString()
{
if (isbottom)
{
if (!isfield)
{
if (Value == null)
return null;
return Convert.ToString("'" + Value + "'");
}
else
{
return Convert.ToString(Value);
}
}
else
{
if(Right==null&& Op=="=")
return Left + " is null ";
else
return Left + " " + Op + " " + Right;
}
}
public static implicit operator ConditionExpression(string value)
{
ConditionExpression condition = new ConditionExpression();
condition.Value = value;
condition.isbottom = true;
return condition;
}
public static implicit operator ConditionExpression(int value)
{
ConditionExpression condition = new ConditionExpression();
condition.Value = value;
condition.isbottom = true;
return condition;
}
public static ConditionExpression operator &(ConditionExpression Condition1, ConditionExpression Condition2)
{
if (Condition1 != null && Condition2 != null)
{
ConditionExpression condition = new ConditionExpression();
condition.Left = Condition1;
condition.Right = Condition2;
condition.Op = "and";
return condition;
}
else if (Condition1 != null)
{
return Condition1;
}
else if (Condition2 != null)
{
return Condition2;
}
return null;
}
public static ConditionExpression operator |(ConditionExpression Condition1, ConditionExpression Condition2)
{
if (Condition1 != null && Condition2 != null)
{
ConditionExpression condition = new ConditionExpression();
condition.Left = Condition1;
condition.Right = Condition2;
condition.Op = "or";
return condition;
}
else if (Condition1 != null)
{
return Condition1;
}
else if (Condition2 != null)
{
return Condition2;
}
return null;
}
private bool IsCompareThan<T>(Type PropertyType)
{
if (PropertyType.Name == typeof(Int32).Name || PropertyType.Name == typeof(Int64).Name ||
PropertyType.Name == typeof(Int16).Name || PropertyType.Name == typeof(float).Name ||
PropertyType.Name == typeof(decimal).Name || PropertyType.Name == typeof(double).Name ||
PropertyType.Name == typeof(DateTime).Name)
{
return true;
}
else return false;
}
private ParameterExpression parameterExpression { get; set; }
private Expression GetBodyExpression<T>(ConditionExpression parent)
{
if (isfield && isbottom)
{
Type PropertyType = typeof(T).GetProperty(parent.Left.ToString()).PropertyType;
if (PropertyType.IsGenericType && PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
PropertyType = PropertyType.GetGenericArguments()[0];
}
Expression ru;
MemberExpression memberExpression = Expression.Property(parent.parameterExpression, Convert.ToString(Value));
if (IsCompareThan<T>(PropertyType))
{
ru = memberExpression;
}
else
{
if (parent.Op == "=")
{
ru = memberExpression;
}
else if (parent.Op == ">" || parent.Op == ">=" || parent.Op == "<" || parent.Op == "<=")
{
MethodInfo method = memberExpression.Type.GetMethod("CompareTo", new Type[] { typeof(string) });
Object Ovalue = Convert.ChangeType(parent.Right.Value, PropertyType);
ConstantExpression rightExpression = Expression.Constant(Ovalue, PropertyType);
MethodCallExpression methodCallExpression = Expression.Call(memberExpression, method, rightExpression);
ru = methodCallExpression;
}
else if (parent.Op == "like")
{
MethodInfo method = memberExpression.Type.GetMethod("Contains", new Type[] { typeof(string) });
Object Ovalue = Convert.ChangeType(parent.Right.Value, PropertyType);
ConstantExpression rightExpression = Expression.Constant(Ovalue, PropertyType);
MethodCallExpression methodCallExpression = Expression.Call(memberExpression, method, rightExpression);
ru = methodCallExpression;
}
else
{
throw new Exception("不支持的比较操作符与数据类型 参考 >=<like");
}
}
return ru;
}
else if (isbottom)
{
Type PropertyType = typeof(T).GetProperty(parent.Left.ToString()).PropertyType;
Type BPropertyType = PropertyType;
ConstantExpression constantExpression = null;
if (PropertyType.IsGenericType && PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
PropertyType = PropertyType.GetGenericArguments()[0];
}
Object Ovalue = Convert.ChangeType(Value, PropertyType);
if (IsCompareThan<T>(PropertyType))
{
constantExpression = Expression.Constant(Ovalue, PropertyType);
}
else
{
if (parent.Op == "=")
{
if (PropertyType.Name == typeof(bool).Name)
{
constantExpression = Expression.Constant(Ovalue, typeof(bool));
}
else
{
constantExpression = Expression.Constant(Value, typeof(string));
}
}
else if (parent.Op == "like")
{
constantExpression = Expression.Constant(true, typeof(bool));
}
else if (parent.Op == ">" || parent.Op == ">=" || parent.Op == "<" || parent.Op == "<=")
{
constantExpression = Expression.Constant(0, typeof(int));
}
else
{
throw new Exception("不支持的比较操作符与数据类型 参考 >=<like");
}
}
Expression typeFilter = constantExpression;
if (BPropertyType.IsGenericType && BPropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
typeFilter = Expression.Convert(constantExpression, BPropertyType);
}
;
return typeFilter;
}
if (Op == ">")
{
parameterExpression = parent.parameterExpression;
Expression body = Expression.GreaterThan(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
return body;
}
if (Op == ">=")
{
parameterExpression = parent.parameterExpression;
Expression body = Expression.GreaterThanOrEqual(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
return body;
}
if (Op == "<")
{
parameterExpression = parent.parameterExpression;
Expression body = Expression.LessThan(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
return body;
}
if (Op == "<=")
{
parameterExpression = parent.parameterExpression;
Expression body = Expression.LessThanOrEqual(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
return body;
}
if (Op == "=")
{
parameterExpression = parent.parameterExpression;
Expression body = Expression.Equal(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
return body;
}
if (Op == "like")
{
parameterExpression = parent.parameterExpression;
Expression body = Expression.Equal(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
return body;
}
if (Op == "and")
{
parameterExpression = parent.parameterExpression;
Expression body = Expression.And(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
return body;
}
if (Op == "or")
{
parameterExpression = parent.parameterExpression;
Expression body = Expression.Or(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
return body;
}
throw new NotImplementedException();
}
public Expression ToExpression<T>(ParameterExpression parameter = null)
{
parameterExpression = Expression.Parameter(typeof(T), "o");
Expression body = GetBodyExpression<T>(this);
Expression expression = Expression.Lambda(body, parameterExpression);
return expression;
}
}
public static class Extensions
{
public static Expression<Func<T, bool>> ToWhereExpression<T>(this Condition condition,bool ignoreTypeError=true )
{
ConditionExpression andCondition = null;
ConditionExpression expression = null;
if (condition != null)
{
if (condition.AndCondition.Count > 0)
{
for (int i = 0; i < condition.AndCondition.Count; i++)
{
if (!string.IsNullOrEmpty(condition.AndCondition[i].Value))
{
ConditionExpression cexpre = new ConditionExpression();
string Field= condition.AndCondition[i].Field;
string Value = condition.AndCondition[i].Value;
if (ignoreTypeError)
{
Type PropertyType = typeof(T).GetProperty(Field).PropertyType;
if (PropertyType.IsGenericType && PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
PropertyType = PropertyType.GetGenericArguments()[0];
}
try
{
if (PropertyType == typeof(bool)&&Value=="1")
{
Value = "true";
}
if (PropertyType == typeof(bool) && Value == "0")
{
Value = "false";
}
Object Ovalue = Convert.ChangeType(Value, PropertyType);
cexpre.Left = Field;
cexpre.Right = Value;
cexpre.Op = condition.AndCondition[i].Op;
}
catch
{
cexpre = null;
}
}
else
{
cexpre.Left = Field;
cexpre.Right = Value;
cexpre.Op = condition.AndCondition[i].Op;
}
andCondition = andCondition & cexpre;
}
}
}
ConditionExpression orCondition = null;
if (condition.OrCondition.Count > 0)
{
for (int i = 0; i < condition.OrCondition.Count; i++)
{
if (!string.IsNullOrEmpty(condition.OrCondition[i].Value))
{
ConditionExpression cexpre = new ConditionExpression();
string Field = condition.OrCondition[i].Field;
string Value = condition.OrCondition[i].Value;
if (ignoreTypeError)
{
Type PropertyType = typeof(T).GetProperty(Field).PropertyType;
if (PropertyType.IsGenericType && PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
PropertyType = PropertyType.GetGenericArguments()[0];
}
try
{
Object Ovalue = Convert.ChangeType(Value, PropertyType);
cexpre.Left = Field;
cexpre.Right = Value;
cexpre.Op = condition.OrCondition[i].Op;
}
catch
{
cexpre = null;
}
}
else
{
cexpre.Left = Field;
cexpre.Right = Value;
cexpre.Op = condition.OrCondition[i].Op;
}
orCondition = orCondition | cexpre;
}
}
}
if (condition.Concat == "and")
{
expression = andCondition & orCondition;
}
if (condition.Concat == "or")
{
expression = andCondition | orCondition;
}
}
if (condition == null|| expression==null)
{
var be = Expression.Equal(Expression.Constant(1), Expression.Constant(1));
var ree = Expression.Lambda(be, Expression.Parameter(typeof(T), "o"));
return (Expression<Func<T, bool>>)ree;
}
LambdaExpression re = (LambdaExpression ) expression.ToExpression<T>();
return (Expression<Func<T, bool>>)re;
}
public static Expression<Func<T, bool>> ToWhereExpression<T>(this IQueryable<T> iqueryable, Condition condition, bool ignoreTypeError = true)
{
ConditionExpression andCondition = null;
ConditionExpression expression = null;
if (condition != null)
{
if (condition.AndCondition.Count > 0)
{
for (int i = 0; i < condition.AndCondition.Count; i++)
{
if (!string.IsNullOrEmpty(condition.AndCondition[i].Value))
{
ConditionExpression cexpre = new ConditionExpression();
string Field = condition.AndCondition[i].Field;
string Value = condition.AndCondition[i].Value;
if (ignoreTypeError)
{
Type PropertyType = typeof(T).GetProperty(Field).PropertyType;
if (PropertyType.IsGenericType && PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
PropertyType = PropertyType.GetGenericArguments()[0];
}
try
{
if (PropertyType == typeof(bool) && Value == "1")
{
Value = "true";
}
if (PropertyType == typeof(bool) && Value == "0")
{
Value = "false";
}
Object Ovalue = Convert.ChangeType(Value, PropertyType);
cexpre.Left = Field;
cexpre.Right = Value;
cexpre.Op = condition.AndCondition[i].Op;
}
catch
{
cexpre = null;
}
}
else
{
cexpre.Left = Field;
cexpre.Right = Value;
cexpre.Op = condition.AndCondition[i].Op;
}
andCondition = andCondition & cexpre;
}
}
}
ConditionExpression orCondition = null;
if (condition.OrCondition.Count > 0)
{
for (int i = 0; i < condition.OrCondition.Count; i++)
{
if (!string.IsNullOrEmpty(condition.OrCondition[i].Value))
{
ConditionExpression cexpre = new ConditionExpression();
string Field = condition.OrCondition[i].Field;
string Value = condition.OrCondition[i].Value;
if (ignoreTypeError)
{
Type PropertyType = typeof(T).GetProperty(Field).PropertyType;
if (PropertyType.IsGenericType && PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
PropertyType = PropertyType.GetGenericArguments()[0];
}
try
{
Object Ovalue = Convert.ChangeType(Value, PropertyType);
cexpre.Left = Field;
cexpre.Right = Value;
cexpre.Op = condition.OrCondition[i].Op;
}
catch
{
cexpre = null;
}
}
else
{
cexpre.Left = Field;
cexpre.Right = Value;
cexpre.Op = condition.OrCondition[i].Op;
}
orCondition = orCondition | cexpre;
}
}
}
if (condition.Concat == "and")
{
expression = andCondition & orCondition;
}
if (condition.Concat == "or")
{
expression = andCondition | orCondition;
}
}
if (condition == null || expression == null)
{
var be = Expression.Equal(Expression.Constant(1), Expression.Constant(1));
var ree = Expression.Lambda(be, Expression.Parameter(typeof(T), "o"));
return (Expression<Func<T, bool>>)ree;
}
LambdaExpression re = (LambdaExpression)expression.ToExpression<T>();
return (Expression<Func<T, bool>>)re;
}
}
public class Condition
{
public Condition()
{
AndCondition = new List<ConditionModel>();
OrCondition = new List<ConditionModel>();
Concat = "and";
}
public List<ConditionModel> AndCondition { get; set; }
public List<ConditionModel> OrCondition { get; set; }
public string Concat { get; set; }
}
public class ConditionModel
{
public string Field { get; set; }
public string Value { get; set; }
public string Op { get; set; }
}
使用方法
var condition= new Condition ()
//第一种 匿名
var query = from a in xxx
select new
{
//
};
query= query.Where(query.ToWhereExpression(condition));
//第二种
condition.OrCondition.Add(
new ConditionModel() { Field = "xxx", Value = 'xxx_SearchValue', Op = "like" }
);
condition.Concat = "and";
condition.AndCondition.Add(
new ConditionModel() { Field = "yyyy", Value = "yyy_SearchValue", Op = "=" }
);
condition.ToWhereExpression<T>();
附加:配合前端使用更舒服
class Pagination{
constructor(PageSize,PageIndex,Sort,SortType,TotalCount,keywords,cdition){
this.PageSize=PageSize
this.PageIndex=PageIndex
this.Sort=Sort
this.SortType=SortType
this.TotalCount=TotalCount
this.keywords=keywords
if(cdition){
if(cdition instanceof condition)
this.cdition=cdition
else
{
console.log('cdition 错误 请用 new condition');
}
}
}
toJSON() {
let obj={
__className: 'Pagination',
PageSize: this.PageSize,
PageIndex: this.PageIndex,
Sort: this.Sort,
SortType: this.SortType,
TotalCount: this.TotalCount,
keywords: this.keywords
}
if(this.cdition)
obj.condition=this.cdition.toJSON()
return obj;
}
static fromJSON(json) {
return new Pagination(
json.PageSize,
json.PageIndex,
json.Sort,
json.SortType,
json.TotalCount,
json.keywords,
json.cdition
);
}
}
class conditionItem{
constructor(Field,Value,Op){
this.Field=Field
this.Value=Value
this.Op=Op
}
toJSON(){
let obj={
__className: 'conditionItem',
Field: this.Field,
Value: this.Value,
Op: this.Op,
}
return obj
}
}
class condition{
constructor(options){
if(options.AndCondition)
{
if(!Array.isArray(options.AndCondition)){
throw new Error('options.AndCondition 必须是conditionItem数组')
}
this.AndCondition=options.AndCondition
}
if(options.OrCondition)
{
if(!Array.isArray(options.OrCondition)){
throw new Error('options.OrCondition 必须是conditionItem数组')
}
this.OrCondition=options.OrCondition
}
if(options.Concat)
this.Concat=options.Concat
}
toJSON(){
let obj={
__className: 'condition'
}
if(this.AndCondition)
{
obj.AndCondition=[]
for (let item of this.AndCondition){
obj.AndCondition.push(item.toJSON())
}
}
if(this.OrCondition)
{
obj.OrCondition=[]
for (let item of this.OrCondition){
obj.OrCondition.push(item.toJSON())
}
}
if(this.Concat)
obj.Concat=this.Concat
return obj;
}
}
/**
var cond=new condition({
AndCondition:[
new conditionItem("name","此","="),
new conditionItem("age","32","=")
],
OrCondition:[]
})
var pagination=new Pagination(12,1,'id','asc',0,'',cond)
var s=pagination.toJSON()
console.log(JSON.stringify(s))
*/
export {Pagination,condition,conditionItem}