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