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

时间:2014-06-13 10:21:26

标签: odata

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

我想要做的是从客户端传递正常的odata $过滤字符串,解析并执行服务器上的过滤器,并在生成的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);
    }

3 个答案:

答案 0 :(得分:0)

尝试使用OData代码生成器生成客户端代码。你可以关注以下博客: How to use OData Client Code Generator to generate client-side proxy class

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

var q2 = TestClientContext.CreateQuery<Type>("Accounts").Where(acct => acct.Birthday > new DateTimeOffset(new DateTime(2013, 10, 1)));

答案 1 :(得分:0)

codeplex中有一些示例代码,用于说明如何进行查询。

检查一下:

https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v3/ODataQueryableSample/Program.cs


<强> 更新

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

编写如下代码:

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.
    }
}

更新2: 您可以从ODataQueryOptions获取过滤器的原始字符串。

    public IQueryable<Order> Get(ODataQueryOptions queryOptions)
    {
        string filterString = queryOptions.Filter.RawValue;
        // Use the filterString
    }

更新3:

(注意:ODataProperties是静态类中的扩展方法 System.Web.Http.OData.Extensions.HttpRequestMessageExtensions

        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);
        }

答案 2 :(得分:0)

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

    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>();
    }