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;
}
}
}