前兩天在園子上看到一個問題前端
半年前我也考慮過這些問題,但因爲這樣那樣的問題,沒有嘗試去解決.數據庫
後來公司用上了 abp vnext ,而後有一部分代碼能夠這樣寫express
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 ); }
用的時候感受仍是有點方便的,但沒怎麼考慮過如何實現,也就這樣一直用着了.ide
看到上面那個問題以後就想起來了這茬兒.ui
衆所周知,去掉 if
的最簡單的方式就是用三元 ()?():()
this
param = string.IsNullOrEmpty(x.CustomerID) ?param :param.And(x => x.CustomerID == query.CustomerID);
講道理,去掉了 if
,可是並無感受比用 if
的時候好多少code
衆所周知,以爲代碼很差看(冗餘多)的時候,你應該作點封裝了blog
通常 來講,查詢時用的應該是 IQueryable<T> Where(......)
字符串
因此能夠對 IQueryable<T>
封裝一些 簡單 的擴展方法get
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();
感受用的時候仍是挺方便簡潔的
再多作點(過分)封裝應該會更好用
抱歉我還在第二層......