有两个班,Foo和Bar。有一个嵌套在Foo对象中的Bar对象。
public class Foo {
public Guid FooId { get; set; }
public string FooName { get; set; }
[ForeignKey("Bar")]
public Guid BarId { get; set; }
public virtual Bar Bar { get; set; }
}
public class Bar {
public Guid BarId { get; set; }
public string BarName { get; set; }
}
public class FooBarContext : DbContext {
public DbSet<Foo> Foos { get; set; }
public DbSet<Bar> Bars { get; set; }
}
public class FooDTO {
public Guid FooId { get; set; }
public string FooName { get; set; }
public Guid BarId { get; set; }
public string BarName { get; set; }
}
我的问题是:我可以以某种方式将FooDTO的OData查询转换为Foo的OData查询,以便它可以应用于Foos DbSet吗?
例如,我想通过BarName进行查询,最终来自嵌套的Bar对象。
GET /Foos?$filter=BarName eq 'Bar2'
这是处理查询的控制器和操作
public class FoosController {
public async Task<IHttpActionResult> GetFoos(ODataQueryOptions<FooDTO> queryOptions) {
// translate filter FooDTO.BarName to filter Foo.Bar.Name
// ODataQueryOptions<Foo> fooQueryOptions = ....
using (var context = new FooBarContext()) {
return fooQueryOptions.ApplyTo(context.Foos);
}
}
}
谢谢。
答案 0 :(得分:2)
首先将OData软件包安装到您的Web API项目中
Install-Package Microsoft.AspNet.OData -Version 7.1.0
通过添加以下WebApiConfig.cs
语句在using
中配置OData端点
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
然后将代码添加到Register
方法
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
// New code start
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Foo>("Foos");
builder.EntitySet<Bar>("Bars");
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: null,
model: builder.GetEdmModel());
config.Count().Filter().OrderBy().Expand().Select().MaxTop(null);
config.EnableDependencyInjection();
// New code end
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
已更新映射:在您的控制器中
[EnableQuery()] // Enables clients to modify the query, by using query options such as $filter, $sort, and $page
public async Task<IHttpActionResult> GetFoos(ODataQueryOptions<FooDTO> queryOptions)
{
using (var context = new FooBarContext())
{
return queryOptions.ApplyTo(context.Foos.AsQueryable().Select(f => new FooDTO
{
BarId = f.BarId,
BarName = f.Bar.BarName,
FooId = f.FooId,
FooName = f.FooName
}));
}
}
有关更多检查,Create an OData v4 Endpoint Using ASP.NET Web API,
也Supercharging your Web APIs with OData and ASP.NET Core(对于.Net核心,但可能有帮助)