|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Collections.ObjectModel;
|
|
|
|
|
using System.Linq.Expressions;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using AutoMapper;
|
|
|
|
|
|
|
|
|
|
namespace DSWeb.Areas.MvcShipping.Helper
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// AutoMapper的帮助类
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static class AutoMapperHelper
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 来源,目标
|
|
|
|
|
/// 单条实体类型映射,默认字段名字一一对应
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="TSource">Dto类型</typeparam>
|
|
|
|
|
/// <typeparam name="TDestination">要被转化的数据</typeparam>
|
|
|
|
|
/// <param name="source">转化之后的实体</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static TDestination MapTo<TSource, TDestination>(this TSource source)
|
|
|
|
|
where TDestination : class, new()
|
|
|
|
|
where TSource : class
|
|
|
|
|
{
|
|
|
|
|
if (source == null) return new TDestination();
|
|
|
|
|
var config = new MapperConfiguration(cfg => cfg.CreateMap<TSource, TDestination>());
|
|
|
|
|
var mapper = config.CreateMapper();
|
|
|
|
|
return mapper.Map<TDestination>(source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 实体列表类型映射,默认字段名字一一对应
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="TDestination">Dto类型</typeparam>
|
|
|
|
|
/// <typeparam name="TSource">要被转化的数据</typeparam>
|
|
|
|
|
/// <param name="source">可以使用这个扩展方法的类型,任何引用类型</param>
|
|
|
|
|
/// <returns>转化之后的实体列表</returns>
|
|
|
|
|
public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source)
|
|
|
|
|
where TDestination : class
|
|
|
|
|
where TSource : class
|
|
|
|
|
{
|
|
|
|
|
if (source == null) return new List<TDestination>();
|
|
|
|
|
var config = new MapperConfiguration(cfg => cfg.CreateMap<TSource, TDestination>());
|
|
|
|
|
var mapper = config.CreateMapper();
|
|
|
|
|
return mapper.Map<List<TDestination>>(source);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
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; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 动态拼接lamba子句
|
|
|
|
|
/// 典型调用方式:
|
|
|
|
|
/// //找到所有需要盘点的库存
|
|
|
|
|
/// List<VW_OP_WMS_AREAGOODS> 符合条件的在库库存 = new List<VW_OP_WMS_AREAGOODS>();
|
|
|
|
|
|
|
|
|
|
/// 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<VW_OP_WMS_AREAGOODS>(Query.Condition.AndAlso)).ToList();
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class QueryCollection : Collection<Query>
|
|
|
|
|
{
|
|
|
|
|
public Expression<Func<T, bool>> AsExpression<T>(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<Expression, Expression, Expression> 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<Func<object>> 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<Func<object>> 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<Func<object>> 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<Func<T, bool>>)Expression.Lambda(expression, parameter));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|