Linq表达式树字符串比较

Linq表达式树字符串比较,linq,expression-trees,Linq,Expression Trees,我试图构造一个表达式树来对字符串数组进行操作。我需要弄清楚如何使用相等的方法 谁能给我举一个 1) 使用Expression.Equal(或.Equals)方法将字符串与常量进行比较, 2) 使用任何类型的表达式使用string.Contains()方法进行筛选 我正在努力学习表达式树机制,但到目前为止,我还没有找到一个好的教程。我非常感谢你的帮助 string[] arr = {"s1","s2","s3"}; IQueryable<String> queryableData =

我试图构造一个表达式树来对字符串数组进行操作。我需要弄清楚如何使用相等的方法

谁能给我举一个
1) 使用Expression.Equal(或.Equals)方法将字符串与常量进行比较,
2) 使用任何类型的表达式使用string.Contains()方法进行筛选

我正在努力学习表达式树机制,但到目前为止,我还没有找到一个好的教程。我非常感谢你的帮助

string[] arr = {"s1","s2","s3"};
IQueryable<String> queryableData = arr.AsQueryable<string>();

// what should go below here?
ParameterExpression p1 = Expression.Parameter(typeof(string), "c");
Expression left = Expression.Constant("s2");
Expression e1 = Expression.Equal(left, p1);

IQueryable<string> res = queryableData.Provider.CreateQuery<string>(e2);
string[]arr={“s1”、“s2”、“s3”};
IQueryable queryableData=arr.AsQueryable();
//下面应该放什么?
ParameterExpression p1=表达式参数(typeof(string),“c”);
表达式左=表达式常数(“s2”);
表达式e1=表达式。相等(左,p1);
IQueryable res=queryableData.Provider.CreateQuery(e2);

啊,我知道你在问什么了。。。你真的进入了一些非常黑暗的领域,这是.NET反射库不适合使用的少数几个领域之一。您必须创建一个调用表达式来调用queryableData对象上的Queryable.Where(),并使用该表达式创建一个新查询。。。问题在于,在.NET中获取方法的通用版本并不一定是您一生中遇到的最简单的事情:

MethodCallExpression call = Expression.Call(
    null, // Calling Queryable.Where(), extension method, not instance method
    getGenericMethod<string>(typeof(Queryable), "Where", typeof(IQueryable<string>), typeof(Expression<Func<string,bool>>)),
    Expression.Constant(queryableData),
    Expression.Lamda(
       e1,
       p1)
);
IQueryable<string> res = queryableData.Provider.CreateQuery<string>(call);
MethodCallExpression call=Expression.call(
null,//调用Queryable.Where(),扩展方法,而不是实例方法
getGenericMethod(typeof(Queryable)、“Where”、typeof(IQueryable)、typeof(Expression)),
表达式.常量(queryableData),
拉姆达(
e1,
p1)
);
IQueryable res=queryableData.Provider.CreateQuery(调用);
您还必须定义getGenericMethod(您可以在其他地方在线找到更好的实现,这是一种非常简单的方法):

private static MethodInfo getGenericMethod(类型类型、字符串名称、参数类型[]参数类型)
{
MethodInfo[]methods=type.GetMethods(名称);
foreach(方法中的MethodInfo mi)
{
如果(!mi.IsGenericMethodDefinition)//或某些类似属性
继续;
if(mi.GetGenericArguments().Length!=1)
继续;
if(mi.GetParameters().Length!=paramTypes.Length)
继续;
MethodInfo genMethod=mi.MakeGenericMethod(新类型[]{typeof(T)});
var ps=genMethod.GetParameters();
bool isGood=true;
对于(int i=0;i

几乎毫无疑问,其中存在一些错误,但我希望您能看到接下来的方向……

仅给出我的解决方案:

string[] arr = {"s1","s2","s3"};
IQueryable<String> queryableData = arr.AsQueryable<string>();
ParameterExpression pe = Expression.Parameter(typeof(string), "company");
Expression right = Expression.Constant("on");
Expression left = Expression.Call(pe, typeof(string).GetMethod("Contains"), right);
MethodCallExpression e2 = Expression.Call(
            typeof(Queryable),
            "Where",
            new Type[] { queryableData.ElementType },
            queryableData.Expression,
            Expression.Lambda<Func<string, bool>>(left, new ParameterExpression[] { pe }));

IQueryable<string> res = queryableData.Provider.CreateQuery<string>(e2);
string[]arr={“s1”、“s2”、“s3”};
IQueryable queryableData=arr.AsQueryable();
ParameterExpression pe=Expression.Parameter(typeof(string),“company”);
表达式右=表达式常数(“开”);
Expression left=Expression.Call(pe,typeof(string).GetMethod(“包含”),right);
MethodCallExpression e2=表达式。调用(
类型(可查询),
“哪里”,
新类型[]{queryableData.ElementType},
queryableData.Expression,
Lambda表达式(左,新参数表达式[]{pe});
IQueryable res=queryableData.Provider.CreateQuery(e2);

您走在了正确的轨道上。。。比较之后的内容肯定是关于构造函数LINQ表达式随需应变的最不直观的部分。希望我的回答能对你有所帮助。。。
string[] arr = {"s1","s2","s3"};
IQueryable<String> queryableData = arr.AsQueryable<string>();
ParameterExpression pe = Expression.Parameter(typeof(string), "company");
Expression right = Expression.Constant("on");
Expression left = Expression.Call(pe, typeof(string).GetMethod("Contains"), right);
MethodCallExpression e2 = Expression.Call(
            typeof(Queryable),
            "Where",
            new Type[] { queryableData.ElementType },
            queryableData.Expression,
            Expression.Lambda<Func<string, bool>>(left, new ParameterExpression[] { pe }));

IQueryable<string> res = queryableData.Provider.CreateQuery<string>(e2);