本文屬於OData系列文章 前文說到了 EDM 與 OData 之間的關係,具有 EDM 的 OData 提供了強大的查詢能力,但是 OData 並不必須要配置 EDM,我們也可以使用 Non-EDM 方案。 Non-EDM 所謂 Non-EDM ,並不是說在 OData 運行時不需要 EDM 配置 ...
本文屬於OData系列文章
前文說到了 EDM
與 OData
之間的關係,具有 EDM
的 OData
提供了強大的查詢能力,但是 OData
並不必須要配置 EDM
,我們也可以使用 Non-EDM
方案。
Non-EDM
所謂 Non-EDM ,並不是說在 OData
運行時不需要 EDM
配置了,而是由 OData
動態生成的 EDM
,進而實現 OData
功能。
配置
配置 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]
。
我們查看 OData 路由,Account
不在路徑中了。
但是我們還是可以使用 OData 語法來進行查詢:
細心的同學發現:
- 我使用了
$count
,但是返回的內容並沒有計數結果。 - 返回對象中沒有
@odata.context
指示對應實體的 EDM 配置信息。 - 在定義了
OData EDM
的對象中,返回數組類型是"Value":[]
的形式,而沒有定義EDM
的對象會直接返回數組對象,這個在與前端進行交互的過程中需要特別註意。
限制
不使用 EDM 模式,在使用 OData 查詢時還是有很多限制:
- 類似$count 之類的語句暫時還不支持。
- 不支持複雜對象(ComplexType)的 $select。
- 無法配置 EntityType 的 Ignore ,不支持一些 OData 的高級特性。
- 不能實現 OData Routing 映射,可能會造成 Versioning 之類的操作困難。
因此,還是建議在使用 OData 時使用並正確配置 EDM,這樣可以獲得最全面的 OData 特性支持。