1,构造表达式树
private
Expression
<
Func
<
Blog,
bool
>>
getCondition()
{
Expression<Func<Blog, bool>> expression = blog => true;
if (!String.IsNullOrEmpty(Request["BlogClassID"]))
{
int blogClassID;
if (Int32.TryParse(Request["BlogClassID"], out blogClassID))
{
Expression<Func<Blog, bool>> e2 = blog => blog.BlogClass == null;
var invokedExpr = Expression.Invoke(e, expression.Parameters.Cast<Expression>());
expression = Expression.Lambda<Func<Blog, bool>>(Expression.And(expression.Body, invokedExpr), expression.Parameters);
}
}
return expression;
}
主查询是这个样子:
{
Expression<Func<Blog, bool>> expression = blog => true;
if (!String.IsNullOrEmpty(Request["BlogClassID"]))
{
int blogClassID;
if (Int32.TryParse(Request["BlogClassID"], out blogClassID))
{
Expression<Func<Blog, bool>> e2 = blog => blog.BlogClass == null;
var invokedExpr = Expression.Invoke(e, expression.Parameters.Cast<Expression>());
expression = Expression.Lambda<Func<Blog, bool>>(Expression.And(expression.Body, invokedExpr), expression.Parameters);
}
}
return expression;
}
var result
=
new
DongBlogDataContext().Blogs.Where(getCondition());
因为根据SQL追踪,生成SQL类似:
SELECT
[
t0
]
.
[
BlogID
]
,
[
t0
]
.
[
ChannelID
]
,
[
t0
]
.
[
BlogClassID
]
,
[
t0
]
.
[
Title
]
,
[
t0
]
.
[
Content
]
,
[
t0
]
.
[
Tag
]
,
[
t0
]
.
[
CreateDateTime
]
FROM [ dbo ] . [ Blog ] AS [ t0 ]
WHERE [ t0 ] . [ BlogClassID ] IS NULL
FROM [ dbo ] . [ Blog ] AS [ t0 ]
WHERE [ t0 ] . [ BlogClassID ] IS NULL
这种方法是实质是合并Lamba表达式,也就是这三句:
Expression
<
Func
<
Blog,
bool
>>
e
=
blog
=>
blog.BlogClass
==
null
;
var invokedExpr = Expression.Invoke(e, expression.Parameters.Cast < Expression > ());
expression = Expression.Lambda < Func < Blog, bool >> (Expression.And(expression.Body, invokedExpr), expression.Parameters);
var invokedExpr = Expression.Invoke(e, expression.Parameters.Cast < Expression > ());
expression = Expression.Lambda < Func < Blog, bool >> (Expression.And(expression.Body, invokedExpr), expression.Parameters);
如果每个条件合并都这么写会很麻烦,幸好已经有人给写好的辅助类:
http://www.albahari.com/expressions/
using
System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T> () { return f => true; }
public static Expression<Func<T, bool>> False<T> () { return f => false; }
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.Or (expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.And (expr1.Body, invokedExpr), expr1.Parameters);
}
}
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T> () { return f => true; }
public static Expression<Func<T, bool>> False<T> () { return f => false; }
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.Or (expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.And (expr1.Body, invokedExpr), expr1.Parameters);
}
}
这个类可以用于Expression<Func<T, bool>>类型的表达式的合并了。具体用法参看
http://www.albahari.com/expressions/或
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1745163&SiteID=1
2,构造Query
同第一种查询更好的写法:
同第一种查询更好的写法:
private
IQueryable
<
Blog
>
getQuery()
{
IQueryable<Blog> query = new DongBlogDataContext().Blogs;
if (!String.IsNullOrEmpty(Request["BlogClassID"]))
{
int blogClassID;
if (Int32.TryParse(Request["BlogClassID"], out blogClassID))
query = query.Where<Blog>(blog => blog.BlogClass == null);
}
return query.OrderByDescending(blog => blog.CreateDateTime);
}
{
IQueryable<Blog> query = new DongBlogDataContext().Blogs;
if (!String.IsNullOrEmpty(Request["BlogClassID"]))
{
int blogClassID;
if (Int32.TryParse(Request["BlogClassID"], out blogClassID))
query = query.Where<Blog>(blog => blog.BlogClass == null);
}
return query.OrderByDescending(blog => blog.CreateDateTime);
}
主查询
var result
=
getQuery();
生成的SQL和第一个完全相同。
本文转自
高阳 51CTO博客,原文链接:http://blog.51cto.com/xiaoyinnet/196448 ,如需转载请自行联系原作者