如何在服务器上使用OData$filter结果

如何在服务器上使用OData$filter结果,odata,Odata,我有一个工作的OData控制器,它支持所有正常的get/put等 我要做的是从客户端传递一个普通的odata$filter字符串,在服务器上解析并执行过滤器,并在生成的IEnumerable上运行一些代码 我把ODataQueryContext、ODataQueryOptions、FilterQueryOption等弄得一团糟,但实际上并没有什么进展 有人有工作的例子吗 编辑:我已经添加了我的函数框架,只需要填充空白 public HttpResponseMessage GetJobs(

我有一个工作的OData控制器,它支持所有正常的get/put等

我要做的是从客户端传递一个普通的odata$filter字符串,在服务器上解析并执行过滤器,并在生成的IEnumerable上运行一些代码

我把ODataQueryContext、ODataQueryOptions、FilterQueryOption等弄得一团糟,但实际上并没有什么进展

有人有工作的例子吗

编辑:我已经添加了我的函数框架,只需要填充空白

    public HttpResponseMessage GetJobs(string filter)
    {
        *** How to convert the filter into IQueryable<Job> ***
        var queryable = ?????    

        var settings = new ODataQuerySettings();
        var jobs = queryOptions.ApplyTo(querable, settings) as IQueryable<Job>;

        CsvSerializer csvSerializer = new CsvSerializer();
        string csv = csvSerializer.Serialise(jobs);
        string fileName = string.Format("{0} Jobs.csv", filter);
        return CreateCsvResponseMessage(csv, fileName);
    }
公共HttpResponseMessage GetJobs(字符串筛选器) { ***如何将筛选器转换为IQueryable*** 变量queryable=????? var设置=新的ODataQuerySettings(); var jobs=queryOptions.ApplyTo(可查询,设置)作为IQueryable; CsvSerializer CsvSerializer=新的CsvSerializer(); 字符串csv=csvSerializer.Serialise(作业); 字符串文件名=string.Format(“{0}Jobs.csv”,过滤器); 返回CreateCsvResponseMessage(csv,文件名); }
尝试使用OData代码生成器生成客户端代码。您可以访问以下博客:

对于过滤器,以下是一个示例:


var q2=TestClientContext.CreateQuery(“账户”)。其中(账户=>账户生日>新日期时间偏移量(新日期时间(2013,10,1))

在codeplex中有一些示例代码来演示如何执行查询

选中此项:


更新:

我给你的示例控制器中有一些示例代码

按如下方式编写代码:

public IQueryable<Order> Get(ODataQueryOptions queryOptions)
{
    if (queryOptions.Filter != null)
    {
        var settings = new ODataQuerySettings();
        var filterResult = queryOptions.ApplyTo(OrderList.AsQueryable(), settings) as IQueryable<Order>;
        // Use the filter result here.
    }
}

我最近有一个场景,我也需要这种功能。这就是我想到的

    private static IQueryable<T> ApplyODataFilter<T>(IQueryable<T> data, string filterString) where T : class
    {
        ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<T>(typeof(T).Name);

        ODataQueryContext context = new ODataQueryContext(builder.GetEdmModel(), typeof(T), new ODataPath());

        ODataQueryOptionParser queryOptionParser = new ODataQueryOptionParser(
            context.Model,
            context.ElementType,
            context.NavigationSource,
            new Dictionary<string, string> { { "$filter", filterString } });

        FilterQueryOption filter = new FilterQueryOption(filterString, context, queryOptionParser);

        IQueryable query2 = filter.ApplyTo(data, new ODataQuerySettings());
        return query2.Cast<T>();
    }
私有静态IQueryable ApplyODataFilter(IQueryable数据,字符串筛选器字符串),其中T:class
{
ODataConventionModelBuilder=新ODataConventionModelBuilder();
builder.EntitySet(typeof(T).Name);
ODataQueryContext上下文=新的ODataQueryContext(builder.getedModel(),typeof(T),new ODataPath());
ODataQueryOptionParser queryOptionParser=新ODataQueryOptionParser(
上下文。模型,
context.ElementType,
context.NavigationSource,
新字典{{“$filter”,filterString});
FilterQueryOption filter=新的FilterQueryOption(filterString,context,queryOptionParser);
IQueryable query2=filter.ApplyTo(数据,新ODataQuerySettings());
返回query2.Cast();
}

谢谢冯,但这不是我想要的。我不想要HttpResponseMessage,因为这样我就必须从HTTP/odata解析回它。我只需要过滤器提供的元素列表。我已经编辑了我的问题,以显示我遇到的困难。如何从筛选器字符串获取IQueryable?我发布了另一个更新,以显示如何从ODataQueryOptions获取筛选器的原始字符串。(注意:queryOptions.filter可以为null)Hi Feng,我已经有了原始字符串,但我没有筛选器!我对问题进行了编辑,使问题更清楚一些。您想要的是将筛选器原始字符串转换为FilterQueryOption,而不是IQueryable。检查我的更新。我的过滤器是odata的,像‘IncidentId eq 5’,所以我认为这个解决方案没有帮助。linq代码将被翻译成odata url,传递到服务器端。那么,您希望在客户端根据响应执行查询吗?否。我希望将odata查询传递给服务器,在服务器上执行,并在服务器上使用IEnumerable结果。客户端的唯一部分是字符串“$filter=Incident eq 5”
        public HttpResponseMessage GetJobs(string filter)
        {
            var context = new ODataQueryContext(Request.ODataProperties().Model, typeof(Job));
            var filterQueryOption = new FilterQueryOption(filter, context);

            IQueryable<Job> queryable = GetAllJobs();
            var settings = new ODataQuerySettings();
            var jobs = filterQueryOption.ApplyTo(queryable, settings) as IQueryable<Job>;

            CsvSerializer csvSerializer = new CsvSerializer();
            string csv = csvSerializer.Serialise(jobs);
            string fileName = string.Format("{0} Jobs.csv", filter);
            return CreateCsvResponseMessage(csv, fileName);
        }
    private static IQueryable<T> ApplyODataFilter<T>(IQueryable<T> data, string filterString) where T : class
    {
        ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<T>(typeof(T).Name);

        ODataQueryContext context = new ODataQueryContext(builder.GetEdmModel(), typeof(T), new ODataPath());

        ODataQueryOptionParser queryOptionParser = new ODataQueryOptionParser(
            context.Model,
            context.ElementType,
            context.NavigationSource,
            new Dictionary<string, string> { { "$filter", filterString } });

        FilterQueryOption filter = new FilterQueryOption(filterString, context, queryOptionParser);

        IQueryable query2 = filter.ApplyTo(data, new ODataQuerySettings());
        return query2.Cast<T>();
    }