C# 如何创建一个动态“contains或LIKE”表达式,用于针对OData服务的Linq

C# 如何创建一个动态“contains或LIKE”表达式,用于针对OData服务的Linq,c#,linq,expression-trees,odata,C#,Linq,Expression Trees,Odata,我正在尝试使用System.Linq.Expressions.Expression WPF/c4.0创建一个动态查询工具 它运行于OData服务 到目前为止,只要我将条件限制在Equal..和GreaterThan.等选项中,所有这些都是有效的。。等 似乎没有内置包含/类似条件,因此我尝试构建自己的。已经有一些文章发表了。我试过的一个是 现在,如果我使用上面的解决方案,得到的表达式是 whereCallExpression = {Convert([10000]).Expand("A,B").Wh

我正在尝试使用System.Linq.Expressions.Expression WPF/c4.0创建一个动态查询工具 它运行于OData服务

到目前为止,只要我将条件限制在Equal..和GreaterThan.等选项中,所有这些都是有效的。。等 似乎没有内置包含/类似条件,因此我尝试构建自己的。已经有一些文章发表了。我试过的一个是

现在,如果我使用上面的解决方案,得到的表达式是

whereCallExpression = {Convert([10000]).Expand("A,B").Where(clt => MyLike(clt.LastName, "te"))}'
这很好,但错了,因为它不能转换为有效的Odata查询

如果我使用条件“Equal”,结果是

whereCallExpression = {Convert([10000]).Expand("A,B").Where(clt => (clt.LastName == "te"))}
这将导致OData查询

results = {http://.../Clients()?$filter=LastName eq 'te'&$expand=A,B} 
并且正在按预期工作

我是否在解决方案的实现上做了一些错误的事情,或者它不能与OData一起使用

它应该转换为…?$filter=substringof'te',LastName eq true

有没有解决办法

问候

安德烈亚斯

另外,我在一个静态类中实现了解决方案扩展,我所做的更改是将被调用方法的名称从“Like”改为“MyLike”
另外,由于用于构建表达式的代码使用的是任何内置条件,因此我假设,目前该部分还可以。如果需要,我可以发布部分内容

OData目前根本不支持like操作符。因此,无论您在客户机上做什么,生成的URL都无法表达这一点。 支持substringof,当您在筛选器Where表达式中使用string.Contains方法时,客户端LINQ提供程序应生成它

要获取由C编译器生成的表达式,可以执行以下操作:

IQueryable<string> source = new List<string>().AsQueryable();
IQueryable<string> result = from item in source where item.Contains("John") select item;
Console.WriteLine(result.Expression.ToString());

基本上,任何IQueryable都有一个属性表达式,其中包含要运行查询的表达式树。一些LINQ提供程序可能会在某种程度上改变由编译器创建的原始表达式树,但大多数应该使其接近原始表达式树。

Thanx对于您的答案@Vitek Karas MSFT,我不太理解您的观点doh。你说我应该使用一个“Contains”选项,但如果我签入“System.Linq.Expressions.Expression”,我看到没有包含,只有字符串是相等的。让我重申我的问题。我可以在svc.clients中使用'var res=从c查询服务,其中c.LastName.CONTAINS。。选择c;'这将生成一个工作查询,与Startswith、Endswith的查询相同。我需要的是在运行时通过表达式树动态创建查询。我是否可能使用了错误的或过时的库?我明白了-Contains只是一个方法调用,因此在表达式树中生成一个表达式。调用字符串。Contains方法并使用正确的参数。LINQ提供程序将识别此模式,并将其视为URL中的子字符串。您可以使用C创建LINQ表达式,因此只需编写from。。。并将结果赋给表达式类型的变量。然后你可以在调试器中检查它,例如,看看C编译器构建了什么表达式树,这样你就可以在自己的代码中模拟它。嗯,这听起来不错。不幸的是,我不知道你的意思是什么,也不知道如何在b中分配a from c的结果。。到表达式类型。可以举个小例子吗?pe=Expression.ParameterTypeOfCyclient,clt;PropertyInfo PropertyInfo=TypeOfCyclient.GetPropertyPropertyFieldName;MemberExpression m=Expression.MakeMemberAccesspe,propertyInfo;ConstantExpression c=表达式。ConstantSearchFrase,typeofstring;MethodInfo mi=TypeOfsString.GetMethodContains,新类型[]{TypeOfsString};e1=exp.Expression.Callm,mi,c;向上投票:谢谢:…?$filter=te的子字符串,LastName eq true