using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq.Expressions; using System.Reflection; using AutoMapper; namespace DSWeb.Areas.MvcShipping.Helper { /// /// AutoMapper的帮助类 /// public static class AutoMapperHelper { /// /// 来源,目标 /// 单条实体类型映射,默认字段名字一一对应 /// /// /// Dto类型 /// 要被转化的数据 /// 转化之后的实体 /// public static TDestination MapTo(this TSource source) where TDestination : class, new() where TSource : class { if (source == null) return new TDestination(); var config = new MapperConfiguration(cfg => cfg.CreateMap()); var mapper = config.CreateMapper(); return mapper.Map(source); } /// /// 实体列表类型映射,默认字段名字一一对应 /// /// Dto类型 /// 要被转化的数据 /// 可以使用这个扩展方法的类型,任何引用类型 /// 转化之后的实体列表 public static List MapToList(this IEnumerable source) where TDestination : class where TSource : class { if (source == null) return new List(); var config = new MapperConfiguration(cfg => cfg.CreateMap()); var mapper = config.CreateMapper(); return mapper.Map>(source); } } /// /// /// public class Query { public enum Operators { None = 0, Equal = 1, GreaterThan = 2, GreaterThanOrEqual = 3, LessThan = 4, LessThanOrEqual = 5, Contains = 6, StartWith = 7, EndWidth = 8, Range = 9 } public enum Condition { OrElse = 1, AndAlso = 2 } public string Name { get; set; } public Operators Operator { get; set; } public object Value { get; set; } public object ValueMin { get; set; } public object ValueMax { get; set; } } /// /// 动态拼接lamba子句 /// 典型调用方式: /// //找到所有需要盘点的库存 /// List 符合条件的在库库存 = new List(); /// QueryCollection queries = new QueryCollection(); /// if(!string.IsNullOrWhiteSpace(head.CUSTOMERNAME)) /// queries.Add(new Query { Name = "CUSTOMERNAME", Operator = Query.Operators.Equal, Value = head.CUSTOMERNAME /// }); ///if (!string.IsNullOrWhiteSpace(head.STOREHOUSE)) /// queries.Add(new Query { Name = "STOREHOUSE", Operator = Query.Operators.Equal, Value = head.STOREHOUSE }); ///if (!string.IsNullOrWhiteSpace(head.GOODSOWNER)) /// queries.Add(new Query { Name = "GOODSOWNER", Operator = Query.Operators.Equal, Value = head.GOODSOWNER }); ///if (!string.IsNullOrWhiteSpace(head.AREACODE)) /// queries.Add(new Query { Name = "AREACODE", Operator = Query.Operators.StartWith, Value = head.AREACODE }); ///符合条件的在库库存 = VW_OP_WMS_AREAGOODSRepository.Instance.FindAsIQueryable(queries.AsExpression(Query.Condition.AndAlso)).ToList(); /// public class QueryCollection : Collection { public Expression> AsExpression(Query.Condition? condition = Query.Condition.OrElse) where T : class { Type targetType = typeof(T); TypeInfo typeInfo = targetType.GetTypeInfo(); var parameter = Expression.Parameter(targetType, "m"); Expression expression = null; Func Append = (exp1, exp2) => { if (exp1 == null) { return exp2; } return (condition ?? Query.Condition.OrElse) == Query.Condition.OrElse ? Expression.OrElse(exp1, exp2) : Expression.AndAlso(exp1, exp2); }; foreach (var item in this) { var property = typeInfo.GetProperty(item.Name); if (property == null || !property.CanRead || (item.Operator != Query.Operators.Range && item.Value == null) || (item.Operator == Query.Operators.Range && item.ValueMin == null && item.ValueMax == null)) { continue; } Type realType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType; if (item.Value != null) { item.Value = Convert.ChangeType(item.Value, realType); } Expression> valueLamba = () => item.Value; switch (item.Operator) { case Query.Operators.Equal: { expression = Append(expression, Expression.Equal(Expression.Property(parameter, item.Name), Expression.Convert(valueLamba.Body, property.PropertyType))); break; } case Query.Operators.GreaterThan: { expression = Append(expression, Expression.GreaterThan(Expression.Property(parameter, item.Name), Expression.Convert(valueLamba.Body, property.PropertyType))); break; } case Query.Operators.GreaterThanOrEqual: { expression = Append(expression, Expression.GreaterThanOrEqual(Expression.Property(parameter, item.Name), Expression.Convert(valueLamba.Body, property.PropertyType))); break; } case Query.Operators.LessThan: { expression = Append(expression, Expression.LessThan(Expression.Property(parameter, item.Name), Expression.Convert(valueLamba.Body, property.PropertyType))); break; } case Query.Operators.LessThanOrEqual: { expression = Append(expression, Expression.LessThanOrEqual(Expression.Property(parameter, item.Name), Expression.Convert(valueLamba.Body, property.PropertyType))); break; } case Query.Operators.Contains: { var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, Expression.Property(parameter, item.Name))); var contains = Expression.Call(Expression.Property(parameter, item.Name), "Contains", null, Expression.Convert(valueLamba.Body, property.PropertyType)); expression = Append(expression, Expression.AndAlso(nullCheck, contains)); break; } case Query.Operators.StartWith: { var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, Expression.Property(parameter, item.Name))); var startsWith = Expression.Call(Expression.Property(parameter, item.Name), "StartsWith", null, Expression.Convert(valueLamba.Body, property.PropertyType)); expression = Append(expression, Expression.AndAlso(nullCheck, startsWith)); break; } case Query.Operators.EndWidth: { var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, Expression.Property(parameter, item.Name))); var endsWith = Expression.Call(Expression.Property(parameter, item.Name), "EndsWith", null, Expression.Convert(valueLamba.Body, property.PropertyType)); expression = Append(expression, Expression.AndAlso(nullCheck, endsWith)); break; } case Query.Operators.Range: { Expression minExp = null, maxExp = null; if (item.ValueMin != null) { var minValue = Convert.ChangeType(item.ValueMin, realType); Expression> minValueLamda = () => minValue; minExp = Expression.GreaterThanOrEqual(Expression.Property(parameter, item.Name), Expression.Convert(minValueLamda.Body, property.PropertyType)); } if (item.ValueMax != null) { var maxValue = Convert.ChangeType(item.ValueMax, realType); Expression> maxValueLamda = () => maxValue; maxExp = Expression.LessThanOrEqual(Expression.Property(parameter, item.Name), Expression.Convert(maxValueLamda.Body, property.PropertyType)); } if (minExp != null && maxExp != null) { expression = Append(expression, Expression.AndAlso(minExp, maxExp)); } else if (minExp != null) { expression = Append(expression, minExp); } else if (maxExp != null) { expression = Append(expression, maxExp); } break; } } } if (expression == null) { return null; } return ((Expression>)Expression.Lambda(expression, parameter)); } } }