2012-04-19 10:38 by 谢中涞, 1330 visits, 收藏, 编辑
本系列目录:
使用EF构建企业级应用(一):主要讲数据库访问基类IRepository及Repository 的实现
使用EF构建企业级应用(二):主要讲动态排序扩展的实现
使用EF构建企业级应用(三):主要讲灵活的构建查询条件表达式Expression<Func<TEntity,bool>>.
使用EF构建企业级应用(四):主要讲下在MVC环境中前端开发中如何邮箱的使用,及一个实例源码包
在前面三篇文章中,我们大致的描述了使用EF如何方便的实现数据持久化,我们简要的回忆下都有那些关键的内容段
- Repository基类的实现,
- 查询条件Expression<Func<T,bool>>的构建
- 排序扩展
那么前端在使用MVC模式的时候,如何方便将我们前面所实现的衔接起来呢? 我们今天就来探讨一下这个问题.
我们先来看看我们在实际项目中是如何使用的,如果你对这个写法有兴趣那再往下看(查询界面我们采用JqGrid来展示数据)
/// <summary>
/// 查询产品列表
/// </summary>
/// <returns></returns>
public ActionResult GetProductList()
{
string json = string.Empty;
if (WebRuntimes.LoginUser == null)
return Content(GetAlertMessageJson("会话已过期,请重新登录"));
try
{
//构件查询条件
var queryParam = GetQueryParam<Product, PgQueryProductExp>();int total = 0;
//查询数据
var lst = SysServices.GetProductList(queryParam, out total);
//将lst转化为jqgrid接受的json格式
json = JsonForJqgrid(lst, total, queryParam.PageSize, queryParam.PageIndex);
}
catch (Exception ex)
{
Logger.Log(ELogType.Error, ex);
json = GetAlertMessageJson("查询失败!");
}return Content(json);
}
也许你很快就发现了上述代码中有两个陌生的方法,构建查询条件及从数据库获取数据,我们分别来看一下这两个方法中都干了什么.
- 首先我们来看看在控制器基类中的构建查询条件的这个方法定义:
123456789101112131415161718192021222324252627282930313233343536373839404142/// <summary>
/// 获取页面分页查询条件
/// </summary>
/// <typeparam name="TEntity">待查询的实体</typeparam>
/// <typeparam name="TPgQueryExp">页面查询转化类型</typeparam>
/// <returns></returns>
protected
EFQueryParam<TEntity> GetQueryParam<TEntity, TPgQueryExp>()
where TEntity :
class
where TPgQueryExp :
class
, IEFQueryExpression<TEntity>,
new
()
{
string
sidx =
"Code"
;
if
(!
string
.IsNullOrEmpty(Request.QueryString[
"sidx"
]))
{
sidx = Request.QueryString[
"sidx"
].ToString();
}
bool
isSordAsc =
false
;
if
(!
string
.IsNullOrEmpty(Request.QueryString[
"sord"
]))
{
if
(Request.QueryString[
"sord"
].ToString() ==
"asc"
)
{
isSordAsc =
true
;
}
}
int
pageSize = System.Convert.ToInt32(Request.QueryString[
"rows"
]);
int
pageIndex = System.Convert.ToInt32(Request.QueryString[
"page"
]) - 1;
IEFQueryExpression<TEntity> exp =
null
;
if
(!
string
.IsNullOrEmpty(Request[
"d"
]))
{
try
{
exp = GetObjectOfJson<TPgQueryExp>(Microsoft.JScript.GlobalObject.unescape(Request[
"d"
]));
}
catch
{ }
}
if
(exp ==
null
)
exp =
new
TPgQueryExp();
EFQueryParam<TEntity> ret =
new
EFQueryParam<TEntity>(exp, sidx, isSordAsc, pageIndex, pageSize);
return
ret;
}
1
|
然后我们来看一下,代码中有个陌生的对象PgQueryProductExp,那么他又做了什么呢?也许你已经猜到了,这个就是页面查询转化条件的,来简要的看一下是如何定义的 |
/// <summary>
/// 页面查询产品条件
/// </summary>
public class PgQueryProductExp : IEFQueryExpression<Product>
{
public string Code { get; set; }
public string Name { get; set; }
public string Specification { get; set; }
public Guid CategoryId { get; set; }
public int EnableFlag { get; set; }public PgQueryProductExp()
{
EnableFlag = 1;
}public Expression<Func<Product, bool>> GetExpression()
{var exp = EFExpression<Product>.CreateSignleLogic(ELogicType.And)
.Like(o => o.Code, Code)
.Like(o => o.Name, Name)
.Like(o => o.Specification, Specification);
if (CategoryId != Guid.Empty)
exp = exp.Equal(o => o.CategoryId, CategoryId);//条件中是否需要判断是否有效?
if (EnableFlag > -1)
{
exp = exp.Equal(o => o.IsEnabled, (EnableFlag == 1));
}return exp.GetExpression();
}
1
|
其次我们来看一下在SysService 这个服务层中,我们是如何实现查询的 |
/// <summary>
/// 查询获取产品数据
/// </summary>
/// <param name="queryParam">查询参数</param>
/// <param name="total">返回符合条件的记录总数</param>
/// <returns></returns>
public IList<Product> GetProductList(EFQueryParam<Product> queryParam, out int total)
{
total = 0;
IList<Product> lst = null;
using (var repository = new Repository<Product>())
{
lst = repository.Include(o => o.ProductCategory).Get(queryParam, out total).ToList();
}
if (lst != null)
lst = lst.Select(o => o.GetJsonEntity()).ToList();
return lst;
}
OK,这个就是一个完整的使用流程,貌似是很简单的吧,不过细心的你也许已经发现了,我们在使用查询的时候,貌似参查询条件数并不是使用的在上一篇文章中的Expression<Func<T,bool>> 模式.而是使用这个EFQueryParam<T>类型.没错,我们在使用的时候,很多兄弟说,这个查询方法的参数太多了,要求封装一下,OK,那我们就来封装一下吧
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374/// <summary>
/// 封装查询参数
/// </summary>
/// <typeparam name="TExpression">参数类型</typeparam>
public
abstract
class
QueryParam<TExpression>
{
/// <summary>
/// 查询条件
/// </summary>
public
TExpression Expression {
get
;
set
; }
/// <summary>
/// 排序字段
/// </summary>
public
string
OrderPropertyName {
get
;
set
; }
/// <summary>
/// 是否是升序排序,为false时则对OrderPropertyName采取降序排序
/// </summary>
public
bool
IsAscSort {
get
;
set
; }
/// <summary>
/// 分页查询,查询第几页
/// </summary>
public
int
PageIndex {
get
;
set
; }
/// <summary>
/// 分页查询,每页显示记录数
/// </summary>
public
int
PageSize {
get
;
set
; }
/// <summary>
/// 指示是否是分页查询
/// </summary>
public
bool
IsPagingQuery {
get
{
return
PageSize > 0; } }
}
/// <summary>
/// EF 实现的 QueryParam
/// </summary>
/// <typeparam name="TEntity">条件关联实体类型</typeparam>
public
class
EFQueryParam<TEntity> : QueryParam<Expression<Func<TEntity,
bool
>>> where TEntity :
class
{
/// <summary>
/// 实例化新的 EFQueryParam 实例
/// </summary>
/// <param name="exp">查询条件</param>
/// <param name="orderPropertyName">排序属性字段名</param>
/// <param name="isAscSort">是否是升序排序,false为降序排序</param>
/// <param name="pageIndex">分页查询,查询第几页</param>
/// <param name="pageSize">分页查询,每页显示记录数</param>
public
EFQueryParam(Expression<Func<TEntity,
bool
>> exp,
string
orderPropertyName,
bool
isAscSort,
int
pageIndex,
int
pageSize)
{
this
.Expression = exp;
this
.OrderPropertyName = orderPropertyName;
this
.IsAscSort = isAscSort;
this
.PageIndex = pageIndex;
this
.PageSize = pageSize;
}
/// <summary>
/// 实例化新的 EFQueryParam 实例
/// </summary>
/// <param name="exp">查询条件</param>
/// <param name="orderPropertyName">排序属性字段名</param>
/// <param name="isAscSort">是否是升序排序,false为降序排序</param>
/// <param name="pageIndex">分页查询,查询第几页</param>
/// <param name="pageSize">分页查询,每页显示记录数</param>
public
EFQueryParam(IEFQueryExpression<TEntity> exp,
string
orderPropertyName,
bool
isAscSort,
int
pageIndex,
int
pageSize) :
this
(exp.GetExpression(), orderPropertyName, isAscSort, pageIndex, pageSize)
{
}
OK,大功告成.本系列也就写完了, 你可以通过这里下载完整的源码包去自己尝试.