6

IQueryable的简单封装

 3 years ago
source link: https://www.cnblogs.com/CollapseNav/p/14197465.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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();

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

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK