Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将OData查询字符串转换为.NET表达式树_.net_Expression_Odata - Fatal编程技术网

如何将OData查询字符串转换为.NET表达式树

如何将OData查询字符串转换为.NET表达式树,.net,expression,odata,.net,Expression,Odata,完全重写这个问题,因为我现在比以前了解得更多 我试图将OData查询字符串的转换直接抽象为.NET表达式树。关于这一点,似乎有很多问题和文章,但没有提供完全依赖于Microsoft.Data.OData命名空间的抽象解决方案的答案(即,所有示例都依赖于WebAPI、实体框架或其他库) 在提供抽象解决方案方面做得最好的答案是: 这两句话让我开始思考: IEdmModel model = EdmxReader.Parse(new XmlTextReader(/*stream of your $me

完全重写这个问题,因为我现在比以前了解得更多

我试图将OData查询字符串的转换直接抽象为.NET表达式树。关于这一点,似乎有很多问题和文章,但没有提供完全依赖于
Microsoft.Data.OData
命名空间的抽象解决方案的答案(即,所有示例都依赖于WebAPI、实体框架或其他库)

在提供抽象解决方案方面做得最好的答案是:

这两句话让我开始思考:

IEdmModel model = EdmxReader.Parse(new XmlTextReader(/*stream of your $metadata file*/));
IEdmEntityType type = model.FindType("organisation");
经过大量的努力,我了解到OData需要EDM来生成自己专有的表达式树模型。这只是一个模型。您必须遍历该模型才能最终生成自己的表达式树

所以我已经做了这一切(某种程度上)。我偶然发现了这篇文章,它向我展示了如何在没有任何导航的情况下创建基本的EDM:

使用它,我最终创建了一个EDM生成器,它通过一个类递归地反映以构建EDM。问题是,这非常复杂,而且在线上没有太多关于如何动态创建EDM的信息,因此它不定义任何导航属性,只适用于单个实体

然后,我创建了一个ODataExpressionVisitor,它以
System.Linq.Expressions.ExpressionVisitor
为模型。它工作得很好。它可以接受以下OData查询字符串:

var filter = ODataUriParser.ParseFilter(
    "(Name eq 'Oxford Mall' or Street eq '123 whatever ln') and Id eq 2",
    edmBuilder.Model, edmBuilder.Model.FindType(typeof(CustomerLocation).FullName));
并生成以下表达式:

(
    $CustomerLocation.Name == "Oxford Mall" || 
    $CustomerLocation.Street == "123 whatever ln"
) && 
$CustomerLocation.Id == 2
它也可以工作,因为我可以将它编译成delagate,并将
CustomerLocation
对象传递到其中,它将返回正确的true/false。不过,我还没有用EF6或其他基于表达式的框架对其进行测试


然而,我认为我在这里重建了一个轮子。必须有一种现有方法1)仅从一个类生成基于约定的EDM,2)将生成的OData表达式树转换为.NET表达式树。

我刚才提到了同样的问题,并用以下方法解决了它:

  • 从ODATA查询字符串创建
    ODataQueryOptions
    ,这可以通过从URI构造它来实现(我在
  • 要将
    ODataQueryOptions
    的各个部分(如
    FilterQueryOption
    转换为
    表达式(实际上是
    MethodCallExpression
    ),我们可以将
    ApplyTo
    与空的
    IQueryable
    结合使用(转换
    OrderByQueryOption
    与此非常类似):


  • 有关更完整的示例,请参见(但最终使用EntityFramework,因此您可能希望跳过其余部分).

    检查以下链接。这是各种语言的官方OData库列表。可能有一个库支持您的需要。@Charles这是一个很好的链接。我现在正在阅读,这是一个很好的帮助。完成后我会发布更新。我正在寻找类似的内容-您成功地使它工作了吗?有一个有许多类似的项目(“Linq To Querystring”和“Linq2Rest”,但它们只对可枚举项应用OData查询,而没有创建有效的表达式树。@mcintyre321是的,但我必须编写自己的EDM生成器OData Expression Tree visitor,然后创建自己的表达式。完整的PIA。由于IP和其他原因,我无法共享它(在公司时间上写的),但这并不容易。上面的Charles的链接让我走上了正确的方向。2年多后,没有人能解决这个问题?让我吃惊的是,微软的堆栈中需要多少库才能从odata筛选器/orderby字符串变为给定类型的表达式
    public static Expression ToExpression<T>(this FilterQueryOption filterQueryOption)
    where T: class
    {
        IQueryable queryable = Enumerable.Empty<T>().AsQueryable();
        queryable = filterQueryOption.ApplyTo(queryable, new OdataQuerySettings());
    
        return queryable.Expression;
    }
    
    var expressionLambda = Expression.Lambda<Func<T, bool>>
        (
            visitedMethodCallExpression.Body, 
            Expression.Parameter(typeof(T), "$it")
        );