针对嵌套的OData创建动态linq表达式树

本文关键字:动态 linq 表达式 创建 OData 嵌套 | 更新日期: 2023-09-27 18:10:56

我需要为针对OData web服务的动态搜索创建一个动态linq表达式。基本的搜索工作,但有嵌套的表,它不工作。

格式为webservice/Books('id')/Author

我可以让这个工作

var authors = from p in webservice.Books.Expand("Author")                        
where p.Title.Equals("Watership Down") && p.Author.FirstName.Equals("Richard") 
select p;

我把它改成如下:

var authors = webservice.Books.Expand("Author").Where(condition);

和I构造条件如下:

ParameterExpression pe = Expression.Parameter(typeof(webservice.Books), "p");
Expression left = Expression.Property(pe, "Title");
Expression right = Expression.Constant("Watership Down"); 
Expression predicateBody = Expression.Equal(left, right);             
Expression<Func<webservice.Books, bool>> condition = Expression.Lambda
            <Func<webservice.Books, bool>>(predicateBody, new ParameterExpression[] { pe });
作品

所以如果我尝试

ParameterExpression pe = Expression.Parameter(typeof(webservice.Books), "p");
Expression left = Expression.Property(pe, "Title");
Expression right = Expression.Constant("Watership Down"); 
Expression e = Expression.Equal(left, right);             
left = Expression.Property(pe, "Author.FirstName");
right = Expression.Constant("Richard"); 
Expression e2 = Expression.Equal(left, right);             
Expression predicateBody = Expression.And(e, e2);             
Expression<Func<webservice.Books, bool>> condition = Expression.Lambda
            <Func<webservice.Books, bool>>(predicateBody, new ParameterExpression[] { pe });

但是它不起作用。它不能识别作者。FirstName作为属性。我认为这是因为我将pe声明为book类型,所以它看不到嵌套的Author,但我不知道如何声明它,所以它会看到嵌套的数据。

确切的错误信息是实例属性'Author '。类型"webServices"没有定义"FirstName"。书'

有人知道怎么做吗?这可能吗?感谢任何人提供的任何帮助。

要解决这个错误,我必须做的是改变left =表达式。属性(pe、"Author.FirstName");来表达式属性=表达式。属性(pe,"作者");left =表达式。财产(财产、"FirstName");

现在它工作了!

谢谢!

针对嵌套的OData创建动态linq表达式树

在这种情况下

left = Expression.Property(pe, "Author.FirstName");

"作者。"FirstName"是属性路径,而不是属性。属性路径通常适用于数据绑定,但不适用于表达式树——您需要更加明确。您需要将其更改为如下内容

var author = Expression.Property(pe, "Author");
left = Expression.Property(author, "FirstName");