using System.Linq.Expressions; using System.Reflection; namespace CmsQueryExtensions.Extension { /// /// 生成Where条件扩展 /// public class WhereConditionsExtensions { public static FunReturnResultModel>> GetWhereConditions(TParam param) { FunReturnResultModel>> result = new FunReturnResultModel>>(); try { Expression> conditions = PredicateExtensions.True(); var errMsg = ""; #region 1、通用查询searchVal //判断通用查询searchVal var pro_value_searchVal = ClassHelper.GetPropertyValue(param, SystemCommonVar.searchVal, out errMsg); if (!string.IsNullOrEmpty(errMsg)) { result.IsSuccess = false; result.ErrMsg = errMsg; return result; } if (!string.IsNullOrEmpty(pro_value_searchVal)) {//表示 通用查询searchVal不为空,需要查询 var pro_value_searchValMode = ClassHelper.GetPropertyValue(param, SystemCommonVar.searchVal_FilterMode, out errMsg); if (!string.IsNullOrEmpty(errMsg)) { result.IsSuccess = false; result.ErrMsg = errMsg; return result; } var pro_value_searchFormInputAttrs = ClassHelper.GetPropertyValueForList(param, SystemCommonVar.searchFormInputAttrs, out errMsg); if (!string.IsNullOrEmpty(errMsg)) { result.IsSuccess = false; result.ErrMsg = errMsg; return result; } if (pro_value_searchFormInputAttrs != null && pro_value_searchFormInputAttrs.Count > 0) { var i_pro_value_searchValMode = Convert.ToInt32(((SearchFilterModeEnum)Enum.Parse(typeof(SearchFilterModeEnum), pro_value_searchValMode))); if (i_pro_value_searchValMode == Convert.ToInt32(SearchFilterModeEnum.模糊查询)) {//模糊查询 try { var new_conditions = PredicateExtensions.GetConditionExpressionForFuzzyQuery(pro_value_searchFormInputAttrs.ToArray(), pro_value_searchVal); //And改为AndAlso,解决mysql 处理And会出错的问题(??And?? 通常对应 ??按位与 (&)??,不会短路求值,可能导致 SQL 生成 NOT (NOT (...)) 这样的冗余逻辑,??AndAlso?? 对应 ??逻辑与 (&&)??,会短路求值,生成的 SQL 更简洁高效。) 【Editby shaocx,2025-05-13】 //conditions = conditions.And(new_conditions); conditions = conditions.Compose(new_conditions, Expression.AndAlso); } catch (Exception ex) { result.data = null; result.IsSuccess = false; result.ErrMsg = ex.Message; return result; } } else if (i_pro_value_searchValMode == Convert.ToInt32(SearchFilterModeEnum.精准查询)) {//精准查询 var new_conditions = PredicateExtensions.GetConditionExpressionForPreciseQuery(pro_value_searchFormInputAttrs.ToArray(), pro_value_searchVal); //And改为AndAlso,解决mysql 处理And会出错的问题(??And?? 通常对应 ??按位与 (&)??,不会短路求值,可能导致 SQL 生成 NOT (NOT (...)) 这样的冗余逻辑,??AndAlso?? 对应 ??逻辑与 (&&)??,会短路求值,生成的 SQL 更简洁高效。) 【Editby shaocx,2025-05-13】 //conditions = conditions.And(new_conditions); conditions = conditions.Compose(new_conditions, Expression.AndAlso); /* pro_value_searchFormInputAttrs.ForEach(x => { if (!string.IsNullOrEmpty(x)) { var myParam = Expression.Parameter(typeof(T)); var condition = Expression.Lambda>( Expression.Equal( Expression.Property(myParam, x), Expression.Constant(pro_value_searchVal, typeof(string)) ), myParam ); // for LINQ to SQl/Entities skip Compile() call conditions = conditions.And(condition); } }); //*/ } else { result.IsSuccess = false; result.ErrMsg = "通用查询配置不正确"; return result; } } } #endregion #region 2、高级查询 var high_pros = FilterHigh_pros(param); List hsmForDatetimeList = new List(); List hsmList = GetHighSearchModelList(param, high_pros, ref hsmForDatetimeList); if (hsmList.Count > 0) { var high_conditions = PredicateExtensions.GetConditionExpressionForHighFieldByAnd(hsmList); //And改为AndAlso,解决mysql 处理And会出错的问题(​​And​​ 通常对应 ​​按位与 (&)​​,不会短路求值,可能导致 SQL 生成 NOT (NOT (...)) 这样的冗余逻辑,​​AndAlso​​ 对应 ​​逻辑与 (&&)​​,会短路求值,生成的 SQL 更简洁高效。) 【Editby shaocx,2025-05-13】 conditions = conditions.Compose(high_conditions, Expression.AndAlso); } if (hsmForDatetimeList.Count > 0) { var high_conditions_dt = PredicateExtensions.GetConditionExpressionForHighFieldByAnd(hsmForDatetimeList); //conditions = conditions.And(high_conditions_dt); conditions = conditions.Compose(high_conditions_dt, Expression.AndAlso); } #endregion result.data = conditions; result.IsSuccess = true; return result; } catch (Exception ex) { throw; } } /// /// 过滤掉Mode后缀的属性 和一些特殊属性的,如DateTimeRange /// /// /// /// /// private static List GetHighSearchModelList(TParam param, List high_pros, ref List hsmForDatetimeList) { List hsmList = new List(); string errMsg = ""; SearchFilterModeEnum _svmEnum = default(SearchFilterModeEnum); var hsmValue = ""; var pro_value = ""; foreach (var pro in high_pros) { if (!pro.Name.Contains(SystemCommonVar.highSearchModeSuffix)) {//不是Mode后缀的字段 //判断是不是有特性特性的值 var _highSearchRangeAttribute = ClassHelper.GetHighSearchRangeAttributeByPro(pro); if (_highSearchRangeAttribute.Length > 0) { object v = ClassHelper.GetPropertyValue(param, pro); if (v == null) { continue; } //判断字符串是否有,号 List arr_value = new List(); string str_arr_value = v as string; if (string.IsNullOrEmpty(str_arr_value)) continue; if (str_arr_value.IndexOf(',') > -1) { var arr = str_arr_value.Split(','); if (arr.Length != 2) continue; arr_value = arr.ToList(); } //string[] arr_value = (string[])v; //string[] arr_value = Convert.ToString(v).Split(','); hsmForDatetimeList.Add(new HighSearchForDateTimeRangeModel() { fieldName = pro.Name, start_fieldValue = arr_value[0], end_fieldValue = arr_value[1] }); continue; } pro_value = ClassHelper.GetPropertyValueByObject(param, pro); if (string.IsNullOrEmpty(pro_value)) { continue; } if (!ClassHelper.IsExistNoAutoQueryAttribute(pro)) { //查找是相应Mode后缀的字段的值 try { //修复查询异常bug 【Editby shaocx,2025-05-03】 SearchFilterModeEnum? _svmEnum_obj = null; _svmEnum_obj = (SearchFilterModeEnum?)ClassHelper.GetPropertyValueForReObject(param, pro.Name + SystemCommonVar.highSearchModeSuffix, out errMsg); if (_svmEnum_obj != null) { _svmEnum = _svmEnum_obj.Value; } else { _svmEnum = SearchFilterModeEnum.不筛选; } } catch (Exception ex) { //处理异常信息 【Editby shaocx,2025-05-03】 _svmEnum = SearchFilterModeEnum.不筛选; } //if (!string.IsNullOrEmpty(errMsg)) //{ // throw new Exception(errMsg); //} //if (hsmValue == "0" || string.IsNullOrEmpty(hsmValue)) //{ // continue; //} //_svmEnum = (SearchFilterModeEnum)Enum.Parse(typeof(SearchFilterModeEnum), hsmValue); if (_svmEnum == SearchFilterModeEnum.不筛选) { continue; } hsmList.Add(new HighSearchModel() { fieldName = pro.Name, fieldValue = pro_value, filterMode = _svmEnum }); } } } return hsmList; } /// /// 过滤一些不需要的字段,如Page、PageSize等 /// /// /// /// private static List FilterHigh_pros(TParam param) { var all_high_pros = ClassHelper.GetPropertyInfoList(param); var high_pros = new List(); //排除不用的 for (int i = 0; i < all_high_pros.Length; i++) { if (!SystemCommonVar.commnParamFatherPros.Contains(all_high_pros[i].Name)) { high_pros.Add(all_high_pros[i]); } } return high_pros; } } }