Пример #1
0
 /// <summary>
 /// 根据放入AutoModelFilterDict的字段(要指定排序功能)自动生成一个对应的ModelSorter用于Sort排序,若SortRuleDict中没有规则,则返回null
 /// </summary>
 /// <returns></returns>
 public Comparison <T> GetModelSorter()
 {
     if (ModelSortRuleDict.IsNullOrEmptySet())
     {
         return(null);
     }
     return(delegate(T modelX, T modelY)
     {
         int result = 0;                                                                                                   //1,-1,0分别是大,小,相等,默认升序
         Dictionary <string, KeyValuePair <Type, object> > modelxInfoDict = ReflectionTool.GetAllPropertyInfo <T>(modelX); //获取一个model字段的信息
         foreach (var modelProperty in modelxInfoDict)
         {
             string fieldName = modelProperty.Key;
             Type type = modelProperty.Value.Key;
             if (ModelSortRuleDict.TryGetValue(fieldName, out KeyValuePair <int, bool> rule) && typeof(IComparable).IsAssignableFrom(type)) //若该字段有排序规则且实现了Comparable接口
             {
                 var xValue = modelProperty.Value.Value;                                                                                    //原始字段值
                 var yValue = typeof(T).GetProperty(fieldName)?.GetValue(modelY);                                                           //要比较的字段值
                 int weight = rule.Key;                                                                                                     //该字段排序权重
                 if (rule.Value)
                 {
                     weight = -weight;            //若该字段是降序则权重相反
                 }
                 weight *= ((IComparable)xValue).CompareTo(yValue);
                 result += weight;
             }
         }
         return result;
     });
 }
Пример #2
0
            //Func<T, object, bool> func = (modelInstance, comparePair) => 的lamada表达式被简化为了本地函数
            static bool func(T modelInstance, object comparePair)
            {
                bool result = true;
                Dictionary <string, KeyValuePair <object, FilterType> > list             = (Dictionary <string, KeyValuePair <object, FilterType> >)comparePair;//[Key属性名 Value[Key属性值,Value过滤类型]]
                Dictionary <string, KeyValuePair <Type, object> >       propertyInfoDict = ReflectionTool.GetAllPropertyInfo <T>(modelInstance);

                if (propertyInfoDict.IsNullOrEmptySet() || comparePair == null)
                {
                    return(true);                                                           //没东西就不用过滤了
                }
                foreach (var contrastPair in list)
                {
                    var pair = contrastPair.Value;
                    if (propertyInfoDict.TryGetValue(contrastPair.Key, out KeyValuePair <Type, object> originPair))
                    {
                        Type       propertyType  = originPair.Key;
                        object     propertyValue = originPair.Value;
                        object     contrast      = pair.Key;
                        FilterType filterType    = pair.Value;
                        var        origin        = propertyValue;//原始字段值


                        //当Str类型支持Empty值时符合则匹配
                        if (filterType.HasFlag(FilterType.SupportStrEmpty) && contrast is string && origin is string && ((string)contrast).IsNullOrEmpty() && ((string)origin).IsNullOrEmpty())
                        {
                            continue;
                        }
                        //原始值是空的不匹配,除非支持null值匹配
                        if (!filterType.HasFlag(FilterType.SupportNull) && origin == null)
                        {
                            return(false);
                        }
                        //原始值是值类型且是默认值的不匹配,除非支持默认值
                        if (origin is ValueType && !filterType.HasFlag(FilterType.SupportValueDefault) && origin.Equals(Activator.CreateInstance(propertyType)))
                        {
                            return(false);
                        }
                        //比较值为空的匹配,因为没有做限制,除非支持null认为null也是限制
                        if (!filterType.HasFlag(FilterType.SupportNull) && contrast == null)
                        {
                            continue;
                        }
                        //当仅过滤空值、默认值时直接匹配(因为前面已经过滤掉了)
                        if (filterType.HasFlag(FilterType.OnlyFilterNull))
                        {
                            continue;
                        }


                        if (origin is string) //类型是string的
                        {
                            string ori = (string)origin;
                            if (ori == string.Empty && !filterType.HasFlag(FilterType.SupportStrEmpty))
                            {
                                return(false);
                            }
                            string con = (string)contrast;
                            switch (filterType)
                            {
                            case var _ when filterType.HasFlag(FilterType.Exact):     //C#7.0特性 case的when约束,要true才会成功case
                            case FilterType.Exact:
                                result &= ori.Equals(con);

                                break;

                            case FilterType.IgnoreCase:
                                result &= ori.Equals(con, StringComparison.OrdinalIgnoreCase);
                                break;

                            case FilterType.Fuzzy:
                                result &= ori.Trim().Contains(con.Trim());
                                break;

                            case FilterType.FuzzyIgnoreCase:
                                result &= ori.ToLower().Trim().Contains(con.ToLower().Trim());
                                break;

                            case FilterType.Interval:    //转为闭区间类型
                                result &= ori.TryGetInterval(out double left, out double right, true) &&
                                          con.TryGetInterval(out double conleft, out double conright, true) &&
                                          (conleft <= left && right <= conright);
                                break;

                            default:
                                goto case FilterType.FuzzyIgnoreCase;
                            }
                        }
                        else if (origin is double || origin is int && contrast is string)//数值型支持区间表示
                        {
                            double ori = System.Convert.ToDouble(origin);
                            string con = (string)contrast;
                            if (ZhNumber.IsContainZhNumber(con))
                            {
                                con = ZhNumber.ToArabicNumber(con);
                            }
                            if (double.TryParse(con, out double num))//直接精确等于
                            {
                                result &= num == ori;
                            }
                            else if (con.TryGetInterval(out IntervalDouble left, out IntervalDouble right))//区间表示
                            {
                                if (!(ori >= left && ori <= right))
                                {
                                    return(false);
                                }
                            }
                            else
                            {
                                return(false);//无法转换则不匹配
                            }
                        }
                        else if (origin is Enum)//支持枚举类过滤
                        {
                            if (contrast is string con)
                            {
                                result &= Enum.Parse(propertyType, con).Equals(origin);
                            }
                            else
                            {
                                result &= contrast.Equals(origin);
                            }
                        }
                        else if (origin is TimeSpan span && contrast is string con)//支持TimeSpan区间型过滤
                        {
                            if (con.TryGetTimeSpan(out TimeSpan timeSpan))
                            {
                                if (timeSpan != span)
                                {
                                    return(false);
                                }
                            }
                            else if (con.TryGetTimeSpanInterval(out TimeSpan left, out TimeSpan right))
                            {
                                if (!(span >= left && span <= right))
                                {
                                    return(false);                                 //不在区间内
                                }
                            }
                            else//尝试古代时间、现代时间以及中文计数法
                            {
                                var    interval     = Regex.Split(con, "(到|[-~,])+");
                                string rightCon     = "";//尝试是否存在第二个以构成区间
                                bool   isRightExist = false;
                                if (interval.Length >= 3)
                                {
                                    con          = interval[0];
                                    rightCon     = interval[2];
                                    isRightExist = true;
                                }
                                TimeSpan zhTimeSpan = new TimeSpan();
                                bool     success    = KouStringTool.TryToTimeSpan(con, out zhTimeSpan);

                                if (success && isRightExist)//如果左边成功了尝试是否有第二个构成区间
                                {
                                    TimeSpan zhTimeSpanRight = new TimeSpan();
                                    bool     successRight    = KouStringTool.TryToTimeSpan(rightCon, out zhTimeSpanRight);
                                    if (!successRight || zhTimeSpan > zhTimeSpanRight || span < zhTimeSpan || span > zhTimeSpanRight)
                                    {
                                        return(false);                                                                                             //原时间间隔不在区间内的不匹配
                                    }
                                }
                                else if (!success || zhTimeSpan != span)
                                {
                                    return(false);                                    //时间与原时间间隔的不一致的不匹配
                                }
                            }
                        }
                        else//其他类型直接比较是否相等
                        {
                            contrast = System.Convert.ChangeType(contrast, propertyType);
                            result  &= contrast.Equals(origin);
                        }
                        if (result == false)
                        {
                            return(false);
                        }
                    }
                }