Kla*_*sen 5 nested filter odata
我有一个C#OData端点,需要在其中评估通过OData查询提交的过滤器,以确定是否需要添加其他过滤器以限制返回给用户的结果。
我的示例模型很简单:
学生->书籍目录->书籍(所有实体均分配有CampusId属性。)
当属于校园#5的用户执行以下查询:“ Students $ select = Id,Name,CampusId”时,应将其转换为:“ Students $ select = Id,Name,CampusId&$ filter = CampusId eq 5”
我可以通过简单地通过将过滤器添加为字符串来进行简单查询。
我真正想做的是:1)确定正在选择和扩展的实体2)确定这些实体是否具有CampusId属性3)在Uri中添加必要的过滤器值,以便对每个选定和/或扩展的查询实体被过滤到该校园
我正在尝试使用Microsoft.OData.Core.UriParser.ODataUriParser解析过滤器值,然后创建一个新的Uri。
例如:
var parser = new Microsoft.OData.Core.UriParser.ODataUriParser(edmModel, new Uri(serviceRootPath), originalUri);
var filter = parser.ParseFilter();
Run Code Online (Sandbox Code Playgroud)
使用上面的代码片段,您将获得“ filter”变量,以提供一种Microsoft.OData.Core.UriParser.Semantic.FilterClause类型,该类型可用于检查OData查询Uri中的当前过滤器值。
有谁知道如何编辑FilterClause中的值以能够向Uri添加新的过滤器值?
我没有找到很多有关如何编辑FilterClause以便生成具有新过滤器值的更新Uri的示例。
我通过编写一种算法找到了解决问题的方法,该算法根据模型的属性向请求 ODataUri 添加额外的过滤。它检查根级别实体的任何属性以及任何扩展实体的属性,以确定要添加到 OData 查询的其他筛选表达式。
OData v4 支持在 $expand 子句中进行筛选,但扩展实体中的 filterOption 是只读的,因此您无法修改扩展实体的筛选表达式。您只能检查展开实体中的filterOption 内容。
我的解决方案是检查所有实体(根实体和扩展实体)的属性,然后在请求 ODataUri 的根过滤器中添加我需要的任何其他 $filter 选项。
以下是 OData 请求 URL 示例:
/RootEntity?$expand=OtherEntity($expand=SomeOtherEntity)
Run Code Online (Sandbox Code Playgroud)
这是我更新后的相同 OData 请求 Url:
/RootEntity?$filter=OtherEntity/SomeOtherEntity/Id eq 3&$expand=OtherEntity($expand=SomeOtherEntity)
Run Code Online (Sandbox Code Playgroud)
我用来实现此目的的步骤:
见下文:
var parser = new ODataUriParser(model, new Uri(serviceRootPath), requestUri);
var odataUri = parser.ParseUri();
Run Code Online (Sandbox Code Playgroud)
第一种方法将检查根实体并根据根实体的属性添加任何其他过滤器。
AddCustomFilters(ref ODataUri odataUri);
Run Code Online (Sandbox Code Playgroud)
AddCustomFilters方法将遍历扩展实体并调用AddCustomFiltersToExpandedEntity,后者将继续遍历所有扩展实体以添加任何必要的过滤器。
foreach (var item in odatauri.SelectAndExpand.SelectedItems)
{
AddCustomFiltersToExpandedEntity(ref ODataUri odataUri, ExpandedNavigationSelectItem expandedNavigationSelectItem, string parentNavigationNameProperty)
}
Run Code Online (Sandbox Code Playgroud)
AddCustomFiltersToExpandedEntity方法应在循环遍历每个级别的扩展实体时调用自身。
根据您的附加过滤器要求创建新的过滤器子句,并覆盖根级别的现有过滤器子句。ODataUri 根级别的 $filter 有一个 setter,因此可以覆盖它。
odataUri.Filter = new FilterClause(newFilterExpression, newFilterRange);
Run Code Online (Sandbox Code Playgroud)
注意:我使用BinaryOperatorKind创建了一个新的过滤器子句。这样任何其他过滤器表达式都会简单地附加到 ODataUri 中已有的任何现有过滤器表达式中
var combinedFilterExpression = new BinaryOperatorNode(BinaryOperatorKind.And, odataUri.Filter.Expression, newFilterExpression);
odataUri.Filter = new FilterClause(combinedFilterExpression, newFilterRange);
Run Code Online (Sandbox Code Playgroud)
见下文:
var updatedODataUri = new Microsoft.OData.Core.UriBuilder.ODataUriBuilder(ODataUrlConventions.Default, odataUri).BuildUri();
Run Code Online (Sandbox Code Playgroud)
这允许 OData 控制器使用更新的 OData Url 完成请求的处理,其中包括您刚刚添加到根级别文件管理器的其他筛选器选项。
ActionContext.Request.RequestUri = updatedODataUri;
Run Code Online (Sandbox Code Playgroud)
这使我能够添加所需的任何过滤选项,并 100% 确定我没有错误地更改 OData Url 结构。
我希望这可以帮助其他人在面临同样的问题时。
| 归档时间: |
|
| 查看次数: |
1068 次 |
| 最近记录: |