EDM 与 OData
之间的关系,具有 EDM
的 OData
提供了强大的查询能力,但是 OData
并不必须要配置 EDM
,我们也可以使用 Non-EDM
方案。
Non-EDM
OData 运行时不需要 EDM
配置了,而是由 OData
动态生成的 EDM
,进而实现 OData
功能。
配置
GetEdmModel(。当然,如果你需要配置路由,因为函数参数需要,我们可以返回一个默认的空 EDM。
services.AddControllers(
.AddOData(opt => opt.Count(.Filter(.Expand(.Select(.OrderBy(.SetMaxTop(5
;
控制器
为了实现 OData 的功能,我们依然需要给控制器与函数上增加一些配置:
[ApiController]
[Route("api/[controller]"]
public class AccountsController : ControllerBase
{
[HttpGet]
public IActionResult Get(ODataQueryOptions<Account> queryOptions
{
var querable = accounts.AsQueryable<Account>(;
var finalQuery = queryOptions.ApplyTo(querable;
return Ok(finalQuery;
}
[HttpGet("{id}"]
public IActionResult Get(Guid id, ODataQueryOptions<Account> queryOptions
{
var accountQuery = accounts.Where(c => c.AccountId == id;
if (!accountQuery.Any(
{
return NotFound(;
}
var finalQuery = queryOptions.ApplyTo(accountQuery.AsQueryable<Account>( as IQueryable<dynamic>;
var result = finalQuery.FirstOrDefault(;
if (result == null
{
return NotFound(;
}
return Ok(result;
}
}
这里代码使用了
ODataQueryOptions
,因此没有使用[EnableQuery]
。
Account 不在路径中了。
- 我使用了
- 返回对象中没有
@odata.context
指示对应实体的 EDM 配置信息。 - 在定义了
OData EDM
的对象中,返回数组类型是"Value":[]
的形式,而没有定义EDM
的对象会直接返回数组对象,这个在与前端进行交互的过程中需要特别注意。
$count
,但是返回的内容并没有计数结果。
限制
不使用 EDM 模式,在使用 OData 查询时还是有很多限制:
- 类似$count 之类的语句暂时还不支持。
- 不支持复杂对象(ComplexType)的 $select。
- 无法配置 EntityType 的 Ignore,不支持一些 OData 的高级特性。
- 不能实现 OData Routing 映射,可能会造成 Versioning 之类的操作困难。
因此,还是建议在使用 OData 时使用并正确配置 EDM,这样可以获得最全面的 OData 特性支持。