如何在c#for Contains中动态创建linq表达式

如何在c#for Contains中动态创建linq表达式,linq,reflection,lambda,entity-framework-core,Linq,Reflection,Lambda,Entity Framework Core,我试图创造表达动态,但我不能想出它。。。也不想像这样使用 if (item.id == 1) filter.AddExpression(c => filterValues.Contains(c.a1)); if (item.id == 2) filter.AddExpression(c => filterValues.Contains(c.a2)); if (item.id == 3) filter.AddExpression(c => filterValues.Contain

我试图创造表达动态,但我不能想出它。。。也不想像这样使用

if (item.id == 1) filter.AddExpression(c => filterValues.Contains(c.a1));
if (item.id == 2) filter.AddExpression(c => filterValues.Contains(c.a2));
if (item.id == 3) filter.AddExpression(c => filterValues.Contains(c.a3));
if (item.id == 4) filter.AddExpression(c => filterValues.Contains(c.a4));


假设您处理
filterValues
TestSubject
属性(
int
int?
)之间的类型不匹配,您可以使用帮助器函数:

public static Expression<Func<TEntity, bool>> MakeContainsLambda<TEntity, TTest>(Expression<Func<ICollection<TTest>>> valsref, string fieldPrefix, string fieldPostfix) {
    var param = Expression.Parameter(typeof(TEntity));
    var vals = valsref.Body;
    var miContains = valsref.Body.Type.GetMethod("Contains", new[] { typeof(TTest) });
    var field = Expression.PropertyOrField(param, fieldPrefix+fieldPostfix);
    var body = Expression.Call(vals, miContains, field);
    return (Expression<Func<TEntity, bool>>) Expression.Lambda(body, param);
}
公共静态表达式MakeContainsLambda(表达式valsref、字符串字段前缀、字符串字段后缀){
var param=表达式参数(typeof(tenty));
var VAL=VALREF.Body;
var miContains=valsref.Body.Type.GetMethod(“Contains”,new[]{typeof(TTest)});
var field=Expression.PropertyOrField(参数,fieldPrefix+fieldPostfix);
var body=Expression.Call(VAL、miContains、field);
return(Expression)Expression.Lambda(body,param);
}
要创建所需的表达式,请执行以下操作:

filter.AddExpression(MakeContainsLambda<TestSubject, int>(() => filterValues, "a", item.id.ToString()));
filter.AddExpression(MakeContainsLambda(()=>filterValues,“a”,item.id.ToString());

假设您处理
filterValues
TestSubject
属性之间的类型不匹配(
int
int?
),您可以使用帮助器函数:

public static Expression<Func<TEntity, bool>> MakeContainsLambda<TEntity, TTest>(Expression<Func<ICollection<TTest>>> valsref, string fieldPrefix, string fieldPostfix) {
    var param = Expression.Parameter(typeof(TEntity));
    var vals = valsref.Body;
    var miContains = valsref.Body.Type.GetMethod("Contains", new[] { typeof(TTest) });
    var field = Expression.PropertyOrField(param, fieldPrefix+fieldPostfix);
    var body = Expression.Call(vals, miContains, field);
    return (Expression<Func<TEntity, bool>>) Expression.Lambda(body, param);
}
公共静态表达式MakeContainsLambda(表达式valsref、字符串字段前缀、字符串字段后缀){
var param=表达式参数(typeof(tenty));
var VAL=VALREF.Body;
var miContains=valsref.Body.Type.GetMethod(“Contains”,new[]{typeof(TTest)});
var field=Expression.PropertyOrField(参数,fieldPrefix+fieldPostfix);
var body=Expression.Call(VAL、miContains、field);
return(Expression)Expression.Lambda(body,param);
}
要创建所需的表达式,请执行以下操作:

filter.AddExpression(MakeContainsLambda<TestSubject, int>(() => filterValues, "a", item.id.ToString()));
filter.AddExpression(MakeContainsLambda(()=>filterValues,“a”,item.id.ToString());

谢谢你的回答是正确的,我的结果如下。对于>=并包含筛选器。。我用于实体框架的查询数据库

    // >=  
    var parameter = Expression.Parameter(typeof(Cx), "Cx"); // Cx Type.
    var member    = Expression.Property(parameter, "a" + fieldNo); //Cx.ay
    var constant  = Expression.Constant(int.Parse(query[fieldNo.ToString()]));
    Expression body     = Expression.GreaterThanOrEqual(member, Expression.Convert(Expression.Constant(int.Parse(query[.ToString()])), member.Type)); // Contains Conversion for GreaterThanOrEqual not accept int , int?
    var finalExpression = Expression.Lambda<Func<Classified, bool>>(body, parameter); 
    filter.AddExpression(finalExpression);           

    // Contains
    var methodInfo      = typeof(List<int?>).GetMethod("Contains", new Type[] { typeof(int?) }); // Contains Method
    var parameter       = Expression.Parameter(typeof(Cx), "Cx"); // Cx Type.
    var member          = Expression.Property(parameter, "a" + fieldNo); //Cx.ay
    var constant        = Expression.Constant(filterValues);
    Expression body     = Expression.Call(Expression.Constant(filterValues), methodInfo, member);
    var finalExpression = Expression.Lambda<Func<Classified, bool>>(body, parameter);
    filter.AddExpression(finalExpression);
/>=
var parameter=Expression.parameter(typeof(Cx),“Cx”);//Cx类型。
var member=Expression.Property(参数“a”+fieldNo)//Cx.ay
var constant=Expression.constant(int.Parse(查询[fieldNo.ToString()]);
Expression body=Expression.GreaterThanOrEqual(成员,表达式.Convert(表达式.Constant(int.Parse(query[.ToString())),成员.类型));//包含大于或等于的转换不接受int,int?
var finalExpression=表达式.Lambda(主体,参数);
filter.AddExpression(finalExpression);
//包含
var methodInfo=typeof(List).GetMethod(“包含”,新类型[]{typeof(int?});//包含方法
var parameter=Expression.parameter(typeof(Cx),“Cx”);//Cx类型。
var member=Expression.Property(参数“a”+fieldNo)//Cx.ay
var常量=表达式常量(FilterValue);
Expression body=Expression.Call(Expression.Constant(filterValues),methodInfo,member);
var finalExpression=表达式.Lambda(主体,参数);
filter.AddExpression(finalExpression);

谢谢你的回答是正确的,我的结果如下。对于>=并包含筛选器。。我用于实体框架的查询数据库

    // >=  
    var parameter = Expression.Parameter(typeof(Cx), "Cx"); // Cx Type.
    var member    = Expression.Property(parameter, "a" + fieldNo); //Cx.ay
    var constant  = Expression.Constant(int.Parse(query[fieldNo.ToString()]));
    Expression body     = Expression.GreaterThanOrEqual(member, Expression.Convert(Expression.Constant(int.Parse(query[.ToString()])), member.Type)); // Contains Conversion for GreaterThanOrEqual not accept int , int?
    var finalExpression = Expression.Lambda<Func<Classified, bool>>(body, parameter); 
    filter.AddExpression(finalExpression);           

    // Contains
    var methodInfo      = typeof(List<int?>).GetMethod("Contains", new Type[] { typeof(int?) }); // Contains Method
    var parameter       = Expression.Parameter(typeof(Cx), "Cx"); // Cx Type.
    var member          = Expression.Property(parameter, "a" + fieldNo); //Cx.ay
    var constant        = Expression.Constant(filterValues);
    Expression body     = Expression.Call(Expression.Constant(filterValues), methodInfo, member);
    var finalExpression = Expression.Lambda<Func<Classified, bool>>(body, parameter);
    filter.AddExpression(finalExpression);
/>=
var parameter=Expression.parameter(typeof(Cx),“Cx”);//Cx类型。
var member=Expression.Property(参数“a”+fieldNo)//Cx.ay
var constant=Expression.constant(int.Parse(查询[fieldNo.ToString()]);
Expression body=Expression.GreaterThanOrEqual(成员,表达式.Convert(表达式.Constant(int.Parse(query[.ToString())),成员.类型));//包含大于或等于的转换不接受int,int?
var finalExpression=表达式.Lambda(主体,参数);
filter.AddExpression(finalExpression);
//包含
var methodInfo=typeof(List).GetMethod(“包含”,新类型[]{typeof(int?});//包含方法
var parameter=Expression.parameter(typeof(Cx),“Cx”);//Cx类型。
var member=Expression.Property(参数“a”+fieldNo)//Cx.ay
var常量=表达式常量(FilterValue);
Expression body=Expression.Call(Expression.Constant(filterValues),methodInfo,member);
var finalExpression=表达式.Lambda(主体,参数);
filter.AddExpression(finalExpression);

包含
不带lambda吗?
查询字段的类型是什么?你看过LINQKit了吗,特别是PredicateBuilder?你的代码没有编译,因为你不能在
列表上用
int?
调用
Contains
。是的,int和int?问题累积,也就是Expression.GreaterThanOrEqual有问题,因此需要使用Expression.Convert。。谢谢
包含
不带lambda?
查询字段的类型是什么?你看过LINQKit了吗,特别是PredicateBuilder?你的代码没有编译,因为你不能在
列表上用
int?
调用
Contains
。是的,int和int?问题累积,也就是Expression.GreaterThanOrEqual有问题,因此需要使用Expression.Convert。。感谢人们在成功解决问题后很少发布最终答案+我为此付出了代价!这对我帮助很大。人们很少在成功解决问题后发布最终答案+我为此付出了代价!这对我帮助很大。