using Masuit.Tools.Mapping.Core;
using System;
using System.Linq;
using System.Linq.Expressions;
namespace Masuit.Tools.Mapping.Extensions
{
///
/// IQueryable的扩展
///
public static class QueryableExtentions
{
///
/// 根据键按升序对序列的元素进行排序。
///
/// 源类型
/// 目标类型
/// 分类化的序列值
/// 目标属性的名称
///
public static IOrderedQueryable OrderBy(this IQueryable query, string sortedPropertyDestName) where TSource : class where TTarget : class
{
// 没有使用MethodBase.GetCurrentMethod().Name,因为效率不高
return CreateSortedMethodCall>(query, "OrderBy", sortedPropertyDestName);
}
///
/// 根据键按降序对序列的元素进行排序。
///
/// 源类型
/// 目标类型
/// 分类化的序列值
/// 目标属性的名称
///
public static IOrderedQueryable OrderByDescending(this IQueryable query, string sortedPropertyDestName) where TSource : class where TTarget : class
{
return CreateSortedMethodCall>(query, "OrderByDescending", sortedPropertyDestName);
}
///
/// 根据键按升序对序列的元素进行排序。
///
/// 源类型
/// 目标类型
/// 分类化的序列值
/// 目标属性的名称
public static IOrderedQueryable ThenBy(this IQueryable query, string sortedPropertyDestName) where TSource : class where TTarget : class
{
return CreateSortedMethodCall>(query, "ThenBy", sortedPropertyDestName);
}
///
/// 根据键按降序对序列的元素进行排序。
///
/// 源类型
/// 目标类型
/// 分类化的序列值
/// 目标属性的名称
public static IOrderedQueryable ThenByDescending(this IQueryable query, string sortedPropertyDestName) where TSource : class where TTarget : class
{
return CreateSortedMethodCall>(query, "ThenByDescending", sortedPropertyDestName);
}
///
/// 通过合并目标对象将序列的每个元素投影到新表单中。
///
/// 源类型.
/// 目标类型.
/// 分类化的序列值
public static IQueryable Select(this IQueryable query) where TSource : class where TTarget : class
{
return GetSelect(query, null);
}
///
/// 通过合并目标对象将序列的每个元素投影到新表单中。
///
/// 源类型.
/// 目标类型.
/// 分类化的序列值
/// mapper别名
///
public static IQueryable Select(this IQueryable query, string mapperName) where TSource : class where TTarget : class
{
return GetSelect(query, mapperName);
}
///
/// 根据谓词过滤一系列值。
///
/// 源类型
/// 目标类型
/// 分类化的序列值
/// 用于根据条件测试每个元素的功能。
///
public static IQueryable Where(this IQueryable query, Expression> predicate)
{
return Queryable.Where(query, predicate.ConvertTo());
}
private static TQueryable CreateSortedMethodCall(IQueryable query, string methodName, string sortedPropertySourceName) where TSource : class where TTarget : class where TQueryable : class, IQueryable
{
MapperConfiguration mapper = ExpressionMapper.GetMapper();
var prop = mapper.GetLambdaDest(sortedPropertySourceName);
var lambda = mapper.GetSortedExpression(sortedPropertySourceName);
MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName, new Type[]
{
typeof(TSource),
prop.Type
}, query.Expression, Expression.Quote(lambda));
return query.Provider.CreateQuery(resultExp) as TQueryable;
}
private static IQueryable GetSelect(IQueryable query, string mapperName) where TSource : class where TTarget : class
{
// 不需要mapper
if (typeof(TSource) == typeof(TTarget))
{
return (IQueryable)query;
}
return query.Select(ExpressionMapper.GetMapper(mapperName).GetLambdaExpression());
}
}
}