我希望将ODataQueryOptions应用于DbSet。让我快速介绍一下我的应用。我需要创建一个从两个表T1和amp;中读取数据的应用程序。 T2。除了每个表之外,两个表都具有几乎相同的模式。我的实体类设计有点像下面所示:(为了简洁起见,我保持了架构和术语的简单化)
class Base
{
[Key]
public int ID;
public string Name;
public string Gender;
public string Comment;
}
[Table("T1")]
class TableOneEntity : Base
{
}
[Table("T2")]
class TableTwoEntity : Base
{
// extra columns from T2
public string Country;
public string City;
}
DbContext类:
class ApplicationDbContext : DbContext
{
public DbSet<TableOneEntity> TableOneDbSet;
public DbSet<TableTwoEntity> TableTwoDbSet;
}
我的OData GET API如下所示:
public PageResult<TableTwoEntity> GetTableResult(ODataQueryOptions<TableOneEntity> options)
{
var result1 = options.ApplyTo(appDbCtx.TableOneDbSet) as IQueryable<TableOneEntity>;
var result2 = options.ApplyTo(appDbCtx.TableTwoDbSet) as IQueryable<TableTwoEntity>;
return new PageResult<TableTwoEntity>(output, odataProperties.NextLink, odataProperties.TotalCount);
}
当调用GET API时,我得到以下异常:
无法将'TableOneEntity'的ODataQueryOptions应用于IQueryable 'TableTwoEntity'。
如何将相同的'选项'应用于TableTwoDbSet?
答案 0 :(得分:0)
我通常会包含对OData WebApi nuget package的引用。
然后,对于控制器,添加Queryable属性并将您的集合作为Queryable返回,您就完成了,只需在调用中添加OData查询选项。
很酷的部分是如果您使用EF,那么所有过滤器和约束都会一直传递到数据库查询。
public class MyController : ApiController
{
// Add the queryable attribute
[Queryable]
IQueryable<stuff> Get() {
...
...
return myStuff.AsQueryable();
}
然后您可以这样使用它:
http://www.blabla.bla/api/v1/stuff?$top=10&$skip=20&$orderby=name
---为你提供10行的第20页,按名称排序。
请参阅OData conventions以获得一个很好的参考:
答案 1 :(得分:0)
管道将URL转换为恰好在一个EDM实体类上的转换。所以简短的回答是,你不能按照自己的方式去做。但是,您可以做的是创建一个复合类(如果您使用EF,则使用视图):
class Base
{
[Key]
public int ID;
public string Name;
public string Gender;
public string Comment;
}
[Table("T1")]
class TableOneEntity : Base
{
}
[Table("T2")]
class TableTwoEntity : Base
{
// extra columns from T2
public string Country;
public string City;
}
[Table("V1")] // which is a view containing columns from Base, T1 and T2.
class CompositeEntity : Base
{
// extra columns from T1
.....
// extra columns from T2
public string Country;
public string City;
}
然后你可以这样做:
[EnableQuery(PageSize = 100)] // For server-driven paging -- recommended but not obligatory
public IHttpActionResult GetTableResult()
{
return appDbCtx.Composite;
}
请记住将复合类添加到EDM(通常在WebApiConfig.cs中)。就是这样。 OData管道将为您完成所有其余的工作。
修改强>
事实上,事实证明,你可以通过使用开放类型来做你想做的事情。见http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/use-open-types-in-odata-v4。但是,我怀疑复合类/视图在您的情况下将是更简单的选项。