using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Diagnostics;
namespace TestLinq.linqToSql
{
/// <summary>
/// 表达式树
/// </summary>
public static class ExpressionExtension
{
public static void Test1()
{
Func<int, bool> deleg = i => i < 5;
Console.WriteLine("deleg(4)={0}", deleg(4));
System.Linq.Expressions.Expression<Func<int, bool>> expr = i => i < 5;
//将表达式树描述的lambda表达式编译为可执行代码,并生成表示该lambda表达式的委托
Func<int, bool> deleg2 = expr.Compile();
Console.WriteLine("deleg2(4)={0}", deleg2(4));
}
public static void Test()
{
#region and 连接linq
Stopwatch s = new Stopwatch();
string[] strArray = new[] {"1", "134562", "321", "123", "456", "36", "dfd"};
s.Start();
Expression<Func<string, bool>> testexpr = True<string>();
testexpr = testexpr.And(x => x.Contains("1"));
testexpr = testexpr.And(x => x.Contains("2"));
var list = strArray.AsQueryable().Where(testexpr);
Console.WriteLine("And测试输出:");
foreach (var str in list)
{
Console.WriteLine(str);
}
s.Stop();
Console.WriteLine(s.Elapsed);
#endregion
s.Restart();
#region or连接linq
Expression<Func<string, bool>> orexpr = False<string>();
orexpr = orexpr.Or(x => x.Contains("1"));
orexpr = orexpr.Or(x => x.Contains("3"));
var orlist = strArray.AsQueryable().Where(orexpr);
Console.WriteLine("Or测试输出:");
foreach (var str in orlist)
{
Console.WriteLine(str);
}
#endregion
s.Stop();
Console.WriteLine(s.Elapsed);
//#region OrderBy
//Expression<Func<string, bool>> orderbyexpr = True<string>();
//orderbyexpr = testexpr.And(x => x.Contains("1"));
//orderbyexpr = testexpr.Or(x => x.Contains("2"));
//var orderlist = strArray.AsQueryable().Where(orderbyexpr).OrderBy("", true);
//#endregion
}
public static void TestModel()
{
GuestSearch guestsearch = new GuestSearch();
guestsearch.StartAge = 200;
guestsearch.EndAge = 100000;
guestsearch.Sex = true;
guestsearch.Name = "3";
List<GuestInfo> gestlist = new List<GuestInfo>();
for (int i = 0; i < 1000000; i++)
{
GuestInfo info = new GuestInfo
{
Name = "Name" + i,
Age = i,
Tel = "13872445357",
Code = i.ToString(),
AddTime=DateTime.Now
};
if (i%2 == 0) info.Sex = true;
gestlist.Add(info);
}
#region And
Stopwatch sw = new Stopwatch();
sw.Start();
Expression<Func<GuestInfo, bool>> sexpr1 = True<GuestInfo>();
if (!string.IsNullOrEmpty(guestsearch.Name))
{
sexpr1=sexpr1.And(x => x.Name.Contains(guestsearch.Name));
}
sexpr1= sexpr1.And(x => x.Age > guestsearch.StartAge && x.Age < guestsearch.EndAge);
sexpr1= sexpr1.And(x => x.Sex);
var test1= gestlist.AsQueryable().Where(sexpr1);
Console.WriteLine(test1.Count());
sw.Stop();
Console.WriteLine("And运行时间:"+sw.Elapsed);
#endregion
sw.Restart();
var test2 = gestlist.Where(o => o.GetSearch(guestsearch));
Console.WriteLine(test2.Count());
sw.Stop();
Console.WriteLine("where运行时间:" + sw.Elapsed);
}
public static bool GetSearch(this GuestInfo guestInfo, GuestSearch guestsearch)
{
if (!string.IsNullOrEmpty(guestsearch.Name))
{
if (!guestInfo.Name.Contains(guestsearch.Name)) return false;
}
if (guestInfo.Age <= guestsearch.StartAge || guestInfo.Age >= guestsearch.EndAge) return false;
if (!guestInfo.Sex) return false;
return true;
}
/// <summary>
/// 构造器
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static Expression<Func<T, bool>> True<T>() { return f =>true; }
public static Expression<Func<T, bool>> False<T>() { return f => false; }
/// <summary>
/// 连接
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="andleft"></param>
/// <param name="andright"></param>
/// <returns></returns>
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> andleft,
Expression<Func<T, bool>> andright)
{
//添加参数
var candidateExpr = Expression.Parameter(typeof(T));
var parameterReplacer = new ParameterReplacer(candidateExpr);
var left = parameterReplacer.Replace(andleft.Body);
var right = parameterReplacer.Replace(andright.Body);
var body = Expression.And(left, right);
return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
}
/// <summary>
/// or连接
/// </summary>
/// <typeparam name="T">模型</typeparam>
/// <param name="andleft">表达式</param>
/// <param name="andright">追加的lamb表达式</param>
/// <returns></returns>
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> andleft, Expression<Func<T, bool>> andright)
{
var candidateExpr = Expression.Parameter(typeof(T));
var parameterReplacer = new ParameterReplacer(candidateExpr);
var left = parameterReplacer.Replace(andleft.Body);
var right = parameterReplacer.Replace(andright.Body);
var body = Expression.Or(left, right);
return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
}
/// <summary>
/// 排序
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="propertyName"></param>
/// <param name="ascending"></param>
/// <returns></returns>
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName, bool ascending) where T : class
{
var type = typeof(T);
var property = type.GetProperty(propertyName);
if (property == null)
throw new ArgumentException(propertyName + "在" + type.Name + "的成员里不存在", propertyName);
var param = Expression.Parameter(type, "p");
Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property);
var orderByExpression = Expression.Lambda(propertyAccessExpression, param);
var methodName = ascending ? "OrderBy" : "OrderByDescending";
var resultExp = Expression.Call(typeof(Queryable), methodName, new Type[] { type, property.PropertyType },
source.Expression, Expression.Quote(orderByExpression));
return source.Provider.CreateQuery<T>(resultExp);
}
/// <summary>
/// 统一ParameterExpression
/// </summary>
internal class ParameterReplacer : ExpressionVisitor
{
public ParameterReplacer(ParameterExpression paramExpr)
{
this.ParameterExpression = paramExpr;
}
public ParameterExpression ParameterExpression { get; private set; }
public Expression Replace(Expression expr)
{
return this.Visit(expr);
}
protected override Expression VisitParameter(ParameterExpression p)
{
return this.ParameterExpression;
}
}
}
}
Linq-Expression表达式树
最新推荐文章于 2018-05-18 17:28:00 发布