根据此文档:http://docs.oasis-open.org/odata/odata/v4.0/errata02/os/complete/part2-url-conventions/odata-v4.0-errata02-os-part2-url-conventions-complete.html#_Toc406398094 我应该能够传递$ filter参数查询,例如“$ filter = contains(PropertyName,'SomeValue')”。
当我传递逻辑运算符时(例如: $ filter = PropertyName eq'TomeValue')它工作正常。但是'contains','substring','endswith','startswith'等函数从不起作用 - 将ODataQueryOptions应用于DbSet的查询结果总是空集。
任何想法为什么?
答案 0 :(得分:2)
所以你的意思是$ filter = contains(PropertyName,' SomeValue')不适合你的服务?该功能本身可以正常使用,请尝试使用http://services.odata.org/TripPinWebApiService/People?$ filter = contains(FirstName,' Angel')。如果您显示代码的更多详细信息,它将帮助其他人解决您的问题。您可以https://github.com/OData/ODataSamples/tree/master/Scenarios/TripPin查看OData V4示例服务的实现,或转到http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/ODataQueryableSample/了解Queryable和$ filter的工作原理。
由于您没有发布您的代码,我不确定问题是什么,我只是快速实施并且$ filter可以正常运行。希望能有所帮助。
Person的模型类
public class Person
{
[Key]
public String ID { get; set; }
[Required]
public String FirstName { get; set; }
[Required]
public String LastName { get; set; }
[Required]
public int Age { get; set; }
public String Description { get; set; }
}
PeopleController.cs
[EnableQuery]
public class PeopleController : ODataController
{
public IHttpActionResult Get()
{
return Ok(DemoDataSources.Instance.People.AsQueryable());
}
}
WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapODataServiceRoute("odata", null, GetEdmModel(), new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
config.EnsureInitialized();
}
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.Namespace = "Demos";
builder.ContainerName = "DefaultContainer";
builder.EntitySet<Person>("People");
var edmModel = builder.GetEdmModel();
return edmModel;
}
}
然后请求可以正常运行http://localhost:21830/People?$filter=contains(Description,'Lorem')
答案 1 :(得分:0)
我终于发现了什么可能是错的,但我不知道如何解决它。
如果我正在尝试传递类似的参数查询:
http://(...)/People?$filter=SomeProperty eq 'Foo'
将OData查询选项应用于我的查询后,在我的WebAPI控制器方法中,即:
IQueryable<People> queryResults = (IQueryable<People>)queryOptions.ApplyTo(query);
在queryResults中有一个类似的片段:
WHERE (`Project1`.`SomeProperty` = @p__linq__0)
一切正常。但当我通过这样的查询时:
http://(...)/People?$filter=contains(SomeProperty, 'Foo')
在queryResults中我可以看到:
WHERE (`Project1`.`SomeProperty` LIKE '%p__linq__0%')
总是没有结果。 我不知道我是否理解正确,但似乎它正在寻找包含文本'p__linq__0'的SomeProperty值,而不是寻找包含p__linq__0的值的值(这是'Foo' )。
感谢您的回复,@ QianLi。 我的控制器看起来像那样:
public class PeopleController : ApiController
{
readonly PeopleContext _context = new PeopleContext();
public PageResult<People> Get(ODataQueryOptions<People> queryOptions)
{
var query = _context.People.OrderBy(x => x.SomeProperty1);
var queryResults = (IQueryable<People>)queryOptions.ApplyTo(query);
long cnt = 0;
if (queryOptions.Count != null)
cnt = long.Parse(Request.Properties["System.Web.OData.TotalCount"].ToString());
return new PageResult<People>(queryResults, null, cnt);
}
}
(这里解释了'cnt'的奇怪解决方法:Items count in OData v4 WebAPI response) 但现在我放弃使用Count,我将控制器实现更改为您所描述的内容:
[EnableQuery]
public class PeopleController : ODataController
{
public IHttpActionResult Get()
{
var query = _context.People.OrderBy(x => x.SomeProperty1);
return Ok(query);
}
}
它的工作原理与之前相同 - 使用 eq 过滤查询, lt 等工作正常,包含根本不起作用
编辑:我知道!问题可能是使用此修复程序的结果:http://www.nuget.org/packages/Patches.System.Web.OData/5.3.0-datetimefixes而不是官方OData库。但我非常需要这个datetimefixes ...