原文:http://www.cnblogs.com/ahui/archive/2011/08/04/2127282.html
EF通用的分页实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/// <summary>
/// 根据条件分页获得记录
/// </summary>
/// <param name="where">条件</param>
/// <param name="orderBy">排序</param>
/// <param name="ascending">是否升序</param>
/// <param name="pageIndex">当前页码</param>
/// <param name="pageSize">每页大小</param>
/// <param name="totalRecord">总记录数</param>
/// <returns>记录列表</returns>
public
virtual
List<T> GetMany(Expression<Func<T,
bool
>>
where
,
string
orderBy,
bool
ascending
,
int
pageIndex,
int
pageSize,
out
int
totalRecord)
{
totalRecord = 0;
where
=
where
.And(u => u.Flag != (
int
)Flags.Delete);
var
list = dbset.Where(
where
);
totalRecord = list.Count();
if
(totalRecord <= 0)
return
new
List<T>();
list = list.OrderBy(orderBy,
ascending
).Skip((pageIndex - 1) * pageSize).Take(pageSize);
return
list.ToList();
}
|
动态排序扩展:
public
static
IQueryable<T> OrderBy<T>(
this
IQueryable<T> source,
string
propertyName,
bool
ascending
)
where
T :
class
{
Type type =
typeof
(T);
PropertyInfo property = type.GetProperty(propertyName);
if
(property ==
null
)
throw
new
ArgumentException(
"propertyName"
,
"Not Exist"
);
ParameterExpression param = Expression.Parameter(type,
"p"
);
Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property);
LambdaExpression orderByExpression = Expression.Lambda(propertyAccessExpression, param);
string
methodName =
ascending
?
"OrderBy"
:
"OrderByDescending"
;
MethodCallExpression resultExp = Expression.Call(
typeof
(Queryable), methodName,
new
Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExpression));
return
source.Provider.CreateQuery<T>(resultExp);
}
|
如果要通过Expression获取字段,可以使用以下代码:
/// <summary>
/// 获取对应的字段名
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="keySelector"></param>
/// <returns></returns>
public
static
string
GetMemberName<TSource, TKey>(Expression<Func<TSource, TKey>> keySelector)
{
string
fieldName =
null
;
var
exp = keySelector.Body
as
UnaryExpression;
if
(exp ==
null
)
{
var
body = keySelector.Body
as
MemberExpression;
fieldName = body.Member.Name;
}
else
{
fieldName = (exp.Operand
as
MemberExpression).Member.Name;
}
return
fieldName;
}
|
多条件组合(参见老赵相关文章):
/// <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;
}
}
public
static
class
PredicateExtensionses
{
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
>> And<T>(
this
Expression<Func<T,
bool
>> exp_left, Expression<Func<T,
bool
>> exp_right)
{
var
candidateExpr = Expression.Parameter(
typeof
(T),
"candidate"
);
var
parameterReplacer =
new
ParameterReplacer(candidateExpr);
var
left = parameterReplacer.Replace(exp_left.Body);
var
right = parameterReplacer.Replace(exp_right.Body);
var
body = Expression.And(left, right);
return
Expression.Lambda<Func<T,
bool
>>(body, candidateExpr);
}
public
static
Expression<Func<T,
bool
>> Or<T>(
this
Expression<Func<T,
bool
>> exp_left, Expression<Func<T,
bool
>> exp_right)
{
var
candidateExpr = Expression.Parameter(
typeof
(T),
"candidate"
);
var
parameterReplacer =
new
ParameterReplacer(candidateExpr);
var
left = parameterReplacer.Replace(exp_left.Body);
var
right = parameterReplacer.Replace(exp_right.Body);
var
body = Expression.Or(left, right);
return
Expression.Lambda<Func<T,
bool
>>(body, candidateExpr);
}
}
|
调用示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public
static
PagedList<UsersDTO> GetUsers(
int
pageIndex,
int
pageSize,
string
orderBy,
bool
ascending
,
Companys company,
string
email,
string
nickName,
bool
? isAdmin, UserStatus userStatus)
{
PagedList<UsersDTO> result =
new
PagedList<UsersDTO>(pageIndex, pageSize);
int
totalRecord = 0;
Expression<Func<Users,
bool
>>
where
= PredicateExtensionses.True<Users>();
if
(company != Companys.All)
where
=
where
.And(u => u.Company == (
int
)company);
if
(!
string
.IsNullOrEmpty(email))
where
=
where
.And(u => u.Email.Contains(email));
if
(!
string
.IsNullOrEmpty(nickName))
where
=
where
.And(u => u.NickName.Contains(nickName));
if
(isAdmin.HasValue)
{
if
(isAdmin.Value)
where
=
where
.And(u => u.IsAdmin == 1);
else
where
=
where
.And(u => u.IsAdmin == 0);
}
if
(userStatus != UserStatus.All)
where
=
where
.And(u => u.UserStatus == (
int
)userStatus);
if
(
string
.IsNullOrEmpty(orderBy))
orderBy = MapHelper.GetMappedName<UsersDTO, Users>(u => u.UserId);
else
orderBy = MapHelper.GetMappedName<UsersDTO, Users>(orderBy);
List<Users> list = _usersDao.GetMany(
where
, orderBy,
ascending
, pageIndex, pageSize,
out
totalRecord);
result.TotalRecordCount = totalRecord;
foreach
(
var
data
in
list)
{
result.Items.Add(Mapper.Map<Users, UsersDTO>(data));
}
return
result;
}
|
上述方法的缺点是无法针对2个字段一起排序,不过只要修改排序参数还是可以实现的!
另外这种分页查询只能针对一个表或者视图