如何用动态LINQ查询重构资产筛选方法?求示例指导
我完全懂你的感受——Expression Trees那堆东西确实有点抽象,绕来绕去容易头大。而动态LINQ正好能帮你绕开这个难点,还能轻松应对以后要加的新参数。下面给你一个实打实的示例,一步步教你实现基于表单随机输入的资产筛选:
第一步:先搞定依赖包
首先需要安装System.Linq.Dynamic.Core这个NuGet包,这是目前.NET生态里最常用的动态LINQ实现,不管是.NET Core还是.NET Framework都能用。
第二步:定义你的资产实体类
先假设你的资产模型是这样的(你可以根据实际业务调整字段):
public class Asset { public string AssetNumber { get; set; } public string AssetName { get; set; } public string Location { get; set; } public DateTime PurchaseDate { get; set; } public decimal CurrentValue { get; set; } // 以后要加新字段直接往这里加就行 }
第三步:重构你的GetAssets方法
原来的方法可能堆了一堆if判断拼接查询条件,现在用动态LINQ来动态生成筛选逻辑:
using System.Linq.Dynamic.Core; using System.Collections.Generic; // 假设你的Status类是用来返回结果的封装类 public Status GetAssets(string assetNumber, string assetName, string location, DateTime? purchaseStartDate, DateTime? purchaseEndDate, decimal? minValue) { // 先获取数据源,比如从数据库Context里拿IQueryable<Asset> IQueryable<Asset> assetQuery = _dbContext.Assets; // 用来存动态筛选条件和对应的参数 var filterConditions = new List<string>(); var queryParameters = new List<object>(); // 逐个处理参数:只有当参数有有效输入时,才添加对应的筛选条件 if (!string.IsNullOrWhiteSpace(assetNumber)) { filterConditions.Add("AssetNumber == @0"); queryParameters.Add(assetNumber); } if (!string.IsNullOrWhiteSpace(assetName)) { // 支持模糊查询,比如包含输入的名称 filterConditions.Add("AssetName.Contains(@1)"); queryParameters.Add(assetName); } if (!string.IsNullOrWhiteSpace(location)) { filterConditions.Add("Location == @2"); queryParameters.Add(location); } if (purchaseStartDate.HasValue) { filterConditions.Add("PurchaseDate >= @3"); queryParameters.Add(purchaseStartDate.Value); } if (purchaseEndDate.HasValue) { filterConditions.Add("PurchaseDate <= @4"); queryParameters.Add(purchaseEndDate.Value); } if (minValue.HasValue) { filterConditions.Add("CurrentValue >= @5"); queryParameters.Add(minValue.Value); } // 把所有条件用AND拼接起来(如果需要OR逻辑,调整拼接符就行) string finalFilter = string.Join(" AND ", filterConditions); // 执行动态查询 if (!string.IsNullOrEmpty(finalFilter)) { assetQuery = assetQuery.Where(finalFilter, queryParameters.ToArray()); } // 这里还可以加排序、分页逻辑,比如按采购日期倒序: // assetQuery = assetQuery.OrderBy("PurchaseDate DESC"); // 获取最终结果 var matchedAssets = assetQuery.ToList(); // 组装你的Status返回值 return new Status { IsSuccess = true, Data = matchedAssets, Message = $"共找到{matchedAssets.Count}条符合条件的资产" }; }
第四步:未来新增参数怎么处理?
比如以后要加一个bool IsInUse的筛选参数,只需要两步:
- 在
GetAssets方法的参数列表里加上bool? isInUse - 添加对应的筛选逻辑:
if (isInUse.HasValue) { filterConditions.Add("IsInUse == @6"); queryParameters.Add(isInUse.Value); }
就这么简单,完全不用动原有逻辑。
几个关键注意点
- 动态LINQ的条件写法和普通Lambda表达式很像,比如
AssetNumber == @0就对应a => a.AssetNumber == assetNumber - 用
@0、@1这种占位符是为了避免SQL注入,动态LINQ会自动处理参数化查询,安全得很 - 支持各种常见操作:Contains、StartsWith、EndsWith、比较运算符(>、<、>=、<=)、逻辑运算符(AND、OR)都能用
内容的提问来源于stack exchange,提问作者Kiran Sankar
相关产品推荐
相关产品推荐

