環境:Visual Studio2008 .NET Framework3.5
場合:查詢條件不確定,需動態生成
動態構造代碼:
1 /**//// <summary>
2 /// 動態構造Lambda表達式
3 /// </summary>
4 /// <typeparam name="T">查詢目標實體</typeparam>
5 public class ConstructLambda<T> where T : class, new()
6 {
7 private Type TType;
8 /**//// <summary>
9 /// 構造方法
10 /// </summary>
11 public ConstructLambda()
12 {
13 TType = typeof(T);
14 }
15 /**//// <summary>
16 /// 構造與表達式
17 /// </summary>
18 /// <param name="dictionary">構造源</param>
19 /// <returns>lambda表達式</returns>
20 public Expression<Func<T, bool>> GetAndLambdaExpression(Dictionary<string, string> dictionary)
21 {
22 Expression expression_return = Expression.Constant(true);
23 ParameterExpression expression_param = Expression.Parameter(TType, "p");
24 foreach (string key in dictionary.Keys)
25 {
26 Expression temp = Expression.Equal(Expression.Call(Expression.Property(expression_param, TType.GetProperty(key)), TType.GetMethod("ToString")),
27 Expression.Constant(dictionary[key]));
28 expression_return = Expression.And(expression_return, temp);
29 }
30 return (Expression<Func<T, bool>>)Expression.Lambda<Func<T, bool>>(expression_return, new ParameterExpression[] { expression_param });
31 }
32
33 /**//// <summary>
34 /// 構造或表達式
35 /// </summary>
36 /// <param name="dictionary">構造源</param>
37 /// <returns>Lambda表達式</returns>
38 public Expression<Func<T, bool>> GetOrLambdaExpression(Dictionary<string, string> dictionary)
39 {
40 Expression expression_return = Expression.Constant(false);
41 ParameterExpression expression_param = Expression.Parameter(TType, "p");
42 foreach (string key in dictionary.Keys)
43 {
44 Expression temp = Expression.Equal(Expression.Call(Expression.Property(expression_param, TType.GetProperty(key)), TType.GetMethod("ToString")),
45 Expression.Constant(dictionary[key]));
46 expression_return = Expression.Or(expression_return, temp);
47 }
48 return (Expression<Func<T, bool>>)Expression.Lambda<Func<T, bool>>(expression_return, new ParameterExpression[] { expression_param });
49 }
50
實例:
測試數據:
虛擬實體:
public class Person
{
public string Name { get; set; }
public string Sex { get; set; }
public int Age { get; set; }
public DateTime Birthday { get; set; }
public Person()
{ }
}
虛擬查找源:
private Dictionary<string, string> dictionary = new Dictionary<string, string>()
{
{"Name","JT"},{"Sex","男"},{"Age","20"},{"Birthday","02/02/2008"}
};
1,無條件查找:
new ConstructLambda<Person>().GetAndLambdaExpression(new Dictionary<string, string>()).ToString()返回結果:
p => True
new ConstructLambda<Person>().GetOrLambdaExpression(new Dictionary<string, string>()).ToString()返回結果:
p => False
2,多條件查找:
new ConstructLambda<Person>().GetAndLambdaExpression(dictionary).ToString()返回結果:
p => ((((True And (p.Name.ToString() = "JT")) And (p.Sex.ToString() = "男")) And (p.Age.ToString() = "20")) And (p.Birthday.ToString() = "02/02/2008"))
回結果:
new ConstructLambda<Person>().GetOrLambdaExpression(dictionary).ToString()返
p => ((((False Or (p.Name.ToString() = "JT")) Or (p.Sex.ToString() = "男")) Or (p.Age.ToString() = "20")) Or (p.Birthday.ToString() = "02/02/2008"))
//構造常量表達式
Expression expression_return = Expression.Constant(true);
//構造表達式參數 類似於p=> 中的p
ParameterExpression expression_param = Expression.Parameter(TType, "p");
//遍歷所有關鍵詞 生成查詢條件
foreach (string key in dictionary.Keys)
{
//生成類似與“p.Name.ToString()==常量”的表達式
Expression temp = Expression.Equal(
//後面兩行先用.Property 得到p.Name 然後用call得到p.Name.ToString();
Expression.Call(
Expression.Property(expression_param, TType.GetProperty(key)),TType.GetMethod("ToString")),
Expression.Constant(dictionary[key]));
//合並查詢條件
expression_return = Expression.And(expression_return, temp);
}
主頁:http://jingtao.cnblogs.com