首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Kendo Grid和Odata数据源对数值列进行字符串包含过滤的最简单方法是什么?

使用Kendo Grid和Odata数据源对数值列进行字符串包含过滤的最简单方法是什么?
EN

Stack Overflow用户
提问于 2019-03-13 05:16:56
回答 1查看 356关注 0票数 1

我有一个带有数据源的kendo网格:

代码语言:javascript
复制
{
    type: 'odata-v4',
    transport: {
        read: '/odata/Books'
    },
    schema: {
        model: {
            id: 'id',
            fields: {
                id: {
                    type: 'number'
                }
            }
        }
    },
    serverPaging: true,
    serverFiltering: true,
    serverSorting: true
}

和C#对象数据控制器:

代码语言:javascript
复制
namespace What.Ever
{
    [System.Web.Http.Authorize]
    [ValidateAntiForgeryToken]
    [EnableQuery]
    public class BooksController : ODataController
    {
        private readonly IDataService _dataService;

        public BooksController(IDataService dataService)
        {
            _dataService = dataService;
        }

        public IHttpActionResult Get()
        {
            var displayData = _dataService.RetrieveData().AsQueryable();

            return Ok(displayData);
        }
    }
}

但我想使用字符串包含筛选器,而不是那种笨拙的数字筛选器,后者对数字it不起作用,因为它很可能用于数字统计。用户将只能输入id的一部分,并返回包含该Id的任何结果。kendo网格需要一个具有字符串'type‘的模式模型,以便使用包含过滤器,而不是数字。但是,如果我将Id设置为字符串类型,那么当网格尝试在字段上执行本机字符串函数时,我会得到一个错误。

我们有一个解决方案是创建一个IdAsString字段,然后在odata url上进行字符串替换,以便在C#/服务器端将其重新设置为'Id‘。这样,它保留了数字排序,但它似乎是一个非常不优雅的解决方案。对于内存中有集合的无odata解决方案,我们通常为每个id字段创建一个字符串版本,然后对其进行自定义排序。否则,如果它是非odata的,并且使用服务器端排序,我们只需使用linq逻辑来实现自定义过滤。

也许我可以将id设置为字符串,然后将其转换为字符串,然后在服务器端实现自定义排序?

这似乎是一个并不罕见的用例,所以我想知道是否有一个很好的解决方案。通过修改kendo配置的一些客户端部分或使用[EnableQuery]属性的服务器端C# odata支持。

在使用Odata和Kendo网格/数据源维护数字排序的同时,对数字id进行字符串包含过滤的最佳方法是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-22 02:28:28

最后,我创建了id字段的字符串版本,但缩短了odata排序服务器端以使用原始的number字段。因此,我们不仅会得到包含过滤,还会得到数值排序,而不是基于字符串的词法排序。

为了替换服务器端的字符串排序,我从控制器/操作中删除了odata [EnableQuery]属性,并添加了一个模板化的ODataQueryOptions参数。使用ODataQueryOptions并调用它的ApplyTo方法几乎取代了[EnableQuery]属性所做的工作。因此,属性和参数在很大程度上是可互换的,但也是互斥的。如果要同时添加这两个选项,odata系统将对同一结果集应用两组odata选项,这可能会导致错误或奇怪的行为。

因此,对于一个示例控制器操作:

代码语言:javascript
复制
[EnableQuery]
public IHttpActionResult Get()
{
    var displayData = _dataService.RetrieveData().AsQueryable();

    return Ok(displayData);
}

变成了:

代码语言:javascript
复制
public IQueryable<Book> Get(ODataQueryOptions<Book> options)
{
    var displayData = _dataService.RetrieveData().AsQueryable();

    _oDataSortingService.ReplaceSingleSortAsStringArguments(options);

    var results = options.ApplyTo(displayData);

    return results as IQueryable<Book>;
}

ReplaceSingleSortAsStringArguments查找任何带有'AsString‘后缀的排序参数,然后操作ODataQueryOptions的排序节点,将AsString字段替换为对应的非后缀字段。

options.OrderBy.OrderByNodes.Clear();将清除电流。然后,您可以在OrderByNodes对象的OrderBy属性上创建一个add an OrderByNode to the ODataQueryOptions list。如下所示:

代码语言:javascript
复制
var entityType = options.Context.ElementType as IEdmEntityType;
var edmProperty = entityType.FindProperty(newSortText);
var nodeDirection = options.OrderBy.OrderByNodes.First().Direction;
options.OrderBy.OrderByNodes.Clear();
options.OrderBy.OrderByNodes.Add(new OrderByPropertyNode(
    edmProperty,
    nodeDirection));

我在查找当前排序参数时遗漏了一些代码,但您可以理解其中的意思。这应该允许同时使用字符串过滤和数字排序。日期可能也是如此,但是您可能需要传递一个时区,以确保字段的字符串版本与用户处于相同的时区。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55130772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档