本文屬於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 特性支援。