Asp.net web api OData v4中的系统查询选项$filter(规范函数)
根据本文件: 我应该能够通过$filter参数查询传递,比如“$filter=contains(PropertyName,'SomeValue')” 当我传递逻辑运算符时(例如: $filter=PropertyName eq'SomeValue')它工作正常。但是像“contains”、“substring”、“endswith”、“startswith”等函数永远不起作用——将ODataQueryOptions应用到DbSet的查询结果总是一个空集Asp.net web api OData v4中的系统查询选项$filter(规范函数),asp.net-web-api,filter,odata,Asp.net Web Api,Filter,Odata,根据本文件: 我应该能够通过$filter参数查询传递,比如“$filter=contains(PropertyName,'SomeValue')” 当我传递逻辑运算符时(例如: $filter=PropertyName eq'SomeValue')它工作正常。但是像“contains”、“substring”、“endswith”、“startswith”等函数永远不起作用——将ODataQueryOptions应用到DbSet的查询结果总是一个空集 你知道为什么吗?那么你是说$filter=
你知道为什么吗?那么你是说$filter=contains(PropertyName,'SomeValue')不适用于你的服务?该功能本身可以很好地工作,请尝试使用?$filter=contains(FirstName,'Angel')。如果您显示代码的更多细节,它将帮助其他人解决您的问题。您可以查看ODataV4示例服务的实现,或者了解Queryable和$filter的工作原理
因为你没有发布你的代码,我不确定是什么问题,我只是有一个快速的实现,$过滤器可以很好地工作。希望这能有所帮助 模范人物
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;
}
}
公共静态类WebApiConfig
{
公共静态无效寄存器(HttpConfiguration配置)
{
config.MapODataServiceRoute(“odata”,null,GetEdmModel(),新的DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
config.EnsureInitialized();
}
私有静态IEdmModel GetEdmModel()
{
ODataConventionModelBuilder=新ODataConventionModelBuilder();
builder.Namespace=“Demos”;
builder.ContainerName=“DefaultContainer”;
建筑商实体集(“人员”);
var edmModel=builder.GetEdmModel();
返回模型;
}
}
然后请求可以工作
http://localhost:21830/People?$filter=contains(Description,'Lorem')
正确我终于发现了可能的错误,但我不知道如何修复它
如果我试图像这样传递参数查询:
http://(...)/People?$filter=SomeProperty eq 'Foo'
WHERE (`Project1`.`SomeProperty` = @p__linq__0)
http://(...)/People?$filter=contains(SomeProperty, 'Foo')
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);
}
}
将OData查询选项应用于我的查询后,在我的WebAPI控制器方法中,即:
IQueryable<People> queryResults = (IQueryable<People>)queryOptions.ApplyTo(query);
一切正常。但当我通过这样的查询时:
http://(...)/People?$filter=SomeProperty eq 'Foo'
WHERE (`Project1`.`SomeProperty` = @p__linq__0)
http://(...)/People?$filter=contains(SomeProperty, 'Foo')
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);
}
}
在queryResults中,我可以看到:
WHERE (`Project1`.`SomeProperty` LIKE '%p__linq__0%')
而且总是没有结果。
我不知道我是否理解正确,但它似乎是在寻找一些包含文本“p__linq__0”的属性值,而不是寻找包含p__linq__0(即“Foo”)的值的值
谢谢你的回复,千里。 我的控制器是这样的:
http://(...)/People?$filter=SomeProperty eq 'Foo'
WHERE (`Project1`.`SomeProperty` = @p__linq__0)
http://(...)/People?$filter=contains(SomeProperty, 'Foo')
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);
}
}
它的工作原理与之前相同-使用eq、lt等过滤查询。工作正常,contains根本不工作
编辑:我知道!问题可能是使用此修复程序而不是官方OData库的结果。但是我非常需要这个datetimefixes…你能将
GET
请求的控制器方法附加到你想要过滤的实体集吗?因为你没有发布你的代码,我不确定是什么问题,我只是在我发布的答案中有一个快速实现,$filter可以很好地工作。希望能有帮助。谢谢。不幸的是,它仍然不起作用。我发布了我的控制器代码。控制器应该继承自ODataController
,而不是ApiController
。是的,它现在继承自ODataController,正如我在上面的帖子中所看到的。它仍然不能正常工作……您是否在返回代码中添加了AsQueryable()
?这就是var query=\u context.People.OrderBy(x=>x.SomeProperty1.AsQueryable()代码>