zoukankan      html  css  js  c++  java
  • IQueryable的简单封装

    IQueryable的简单封装

    前言

    前两天在园子上看到一个问题

    半年前我也考虑过这些问题,但由于这样那样的问题,没有尝试去解决.

    后来公司用上了 abp vnext ,然后有一部分代码可以这样写

    protected override IQueryable<Resource> CreateFilteredQuery(GetResourceDto input)
    {
        return ReadOnlyRepository.WhereIf(
            input.ParentId.HasValue,
            item => item.ParentId == input.ParentId
        ).WhereIf(
            input.Id.HasValue,
            item => item.Id == input.Id
        );
    }
    

    用的时候感觉还是有点方便的,但没怎么考虑过如何实现,也就这样一直用着了.

    看到上面那个问题之后就想起来了这茬儿.

    第一阶段

    众所周知,去掉 if 的最简单的方式就是用三元 ()?():()

    param = string.IsNullOrEmpty(x.CustomerID)
            ?param
            :param.And(x => x.CustomerID == query.CustomerID);
    

    讲道理,去掉了 if ,但是并没有感觉比用 if 的时候好多少

    第二阶段

    众所周知,觉得代码不好看(冗余多)的时候,你应该做点封装了

    一般 来说,查询时用的应该是 IQueryable<T> Where(......)

    所以可以对 IQueryable<T> 封装一些 简单 的扩展方法

    public static class QueryClass
    {
        public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool flag, Expression<Func<T, bool>> expression)
        {
            return flag ? query.Where(expression) : query;
        }
    
        public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, string flag, Expression<Func<T, bool>> expression)
        {
            return string.IsNullOrEmpty(flag) ? query : query.Where(expression);
        }
    }
    

    用的时候就比较简单了

    先定义一下(数据库)实体

    public class Entity
    {
        // 可为空
        public Guid? Id { get; set; }
        // 字符串
        public string Name { get; set; }
        // 值类型
        public int Num { get; set; }
    }
    

    以上应该是程序里面用到的最多的3种数据类型了(大概)

    然后整点数据

    List<Entity> list = new()
    {
        new Entity { Id = Guid.NewGuid(), Name = "2" },
        new Entity { Id = Guid.NewGuid(), Name = "233333" },
        new Entity { Id = Guid.NewGuid(), Name = "233333", Num = 233333 },
        new Entity { Id = Guid.NewGuid(), Name = "233333", Num = 3 },
        new Entity { Id = Guid.NewGuid(), Name = "23" },
        ......
        ......
        new Entity { Id = Guid.NewGuid(), Name = "23", Num = 2333 },
    };
    

    然后前端传了点数据过来

    Entity input = new()
    {
        Id = null,
        Name = "233",
        Num = 233
    };
    

    写条件的时候大概就像下面这样

    var result = list.AsQueryable()
    .WhereIf(input.Id.HasValue, item => item.Id == input.Id)
    .WhereIf(input.Name, item => item.Name.Contains(input.Name))
    .WhereIf(input.Num > 0, item => item.Num > input.Num * 20).ToList();
    

    感觉用的时候还是挺方便简洁的

    再多做点(过度)封装应该会更好用

    第三阶段

    抱歉我还在第二层......

  • 相关阅读:
    <记录> axios 模拟表单提交数据
    PHP 设计模式(一)
    CSS3中translate、transform和translation的区别和联系
    微信小程序 支付功能 服务器端(TP5.1)实现
    微信小程序 用户登录 服务器端(TP5.1)实现
    <记录> curl 封装函数
    <记录>TP5 关联模型使用(嵌套关联、动态排序以及隐藏字段)
    PHP/TP5 接口设计中异常处理
    TP5 自定义验证器
    高并发和大流量解决方案--数据库缓存
  • 原文地址:https://www.cnblogs.com/CollapseNav/p/14197465.html
Copyright © 2011-2022 走看看