您现在的位置是:网站首页> 编程资料编程资料

ASP.NET MVC5网站开发之用户添加和浏览2(七)_实用技巧_

2023-05-24 252人已围观

简介 ASP.NET MVC5网站开发之用户添加和浏览2(七)_实用技巧_

一、数据存储层

1、查找分页列表

在写用户列表时遇到了问题,考虑到用户可能会较多的情况需要分页,在数据存储层写的方法是public IQueryable FindPageList(int pageSize, int pageIndex, out int totalNumber, Expression> where, Expression> order, bool asc)。

主要问题就在红色的order这儿,这个参数不好传递,比如:如果是已ID来排序哪TKey类型是int,如果以注册时间来排序哪TKey类型就是datetime。如果我在业务逻辑层写一个函数可以支持选择排序类型,那么我没有办法声明一个变量既可以存储TKey为int的值,又可以存储datetime的值,那么排序就要写成下面这个样子,感觉不舒服。

//排序 switch(order) { case 0://ID升序 _users.Items = Repository.FindPageList((int)pageSize, (int)pageIndex, out _users.TotalNumber, _where, u => u.UserID, true).ToList(); break; case 1://ID降序 _users.Items = Repository.FindPageList((int)pageSize, (int)pageIndex, out _users.TotalNumber, _where, u => u.UserID, false).ToList(); break; case 2://注册时间降序 _users.Items = Repository.FindPageList((int)pageSize, (int)pageIndex, out _users.TotalNumber, _where, u => u.RegTime, true).ToList(); break; case 3://注册时间升序 _users.Items = Repository.FindPageList((int)pageSize, (int)pageIndex, out _users.TotalNumber, _where, u => u.RegTime, false).ToList(); break; case 4://最后登录时间升序 _users.Items = Repository.FindPageList((int)pageSize, (int)pageIndex, out _users.TotalNumber, _where, u => u.LastLoginTime, true).ToList(); break; case 5://最后登录时间降序 _users.Items = Repository.FindPageList((int)pageSize, (int)pageIndex, out _users.TotalNumber, _where, u => u.LastLoginTime, false).ToList(); break; default://ID降序 _users.Items = Repository.FindPageList((int)pageSize, (int)pageIndex, out _users.TotalNumber, _where, u => u.UserID, false).ToList(); break; }

后来将TKey设为dynamic类型,不论Expression> order = u => u.UserID  或者u => u.RegTime都可以编译通过,但是一运行就会出错。

前几天没写博客一直在考虑这个问题,后来还是换成用字符串的方式来动态排序。 步骤如下:

Ninesky.DataLibrary[右键]->添加->类,输入类名OrderParam

namespace Ninesky.DataLibrary { ///  /// 排序参数 ///  public class OrderParam { ///  /// 属性名 ///  public string PropertyName { get; set; } ///  /// 排序方式 ///  public OrderMethod Method { get; set; } } ///  /// 排序方式 ///  public enum OrderMethod { ///  /// 正序 ///  ASC, ///  /// 倒序 ///  DESC } } 

打开Ninesky.DataLibrary/Repository.cs,将方法public IQueryable FindPageList(int pageSize, int pageIndex, out int totalNumber, Expression> where, Expression> order, bool asc)的代码修改为

///  /// 查找分页列表 ///  /// 每页记录数。必须大于1 /// 页码。首页从1开始,页码必须大于1 /// 总记录数 /// 查询表达式 /// 排序【null-不设置】 public IQueryable FindPageList(int pageSize, int pageIndex, out int totalNumber, Expression> where, OrderParam[] orderParams) { if (pageIndex < 1) pageIndex = 1; if (pageSize < 1) pageSize = 10; IQueryable _list = DbContext.Set().Where(where); var _orderParames = Expression.Parameter(typeof(T), "o"); if (orderParams != null && orderParams.Length > 0) { for (int i = 0; i < orderParams.Length; i++) { //根据属性名获取属性 var _property = typeof(T).GetProperty(orderParams[i].PropertyName); //创建一个访问属性的表达式 var _propertyAccess = Expression.MakeMemberAccess(_orderParames, _property); var _orderByExp = Expression.Lambda(_propertyAccess, _orderParames); string _orderName = orderParams[i].Method == OrderMethod.ASC ? "OrderBy" : "OrderByDescending"; MethodCallExpression resultExp = Expression.Call(typeof(Queryable), _orderName, new Type[] { typeof(T), _property.PropertyType }, _list.Expression, Expression.Quote(_orderByExp)); _list = _list.Provider.CreateQuery(resultExp); } } totalNumber = _list.Count(); return _list.Skip((pageIndex - 1) * pageIndex).Take(pageSize); }

方法中排序参数(OrderParam[]) 使用数组,是考虑到多级排序的情况。对FindPageList重载代码进行修改,修改完的代码如下:

 //查找实体分页列表 #region FindPageList ///  /// 查找分页列表 ///  /// 每页记录数。必须大于1 /// 页码。首页从1开始,页码必须大于1 /// 总记录数 ///  public IQueryable FindPageList(int pageSize, int pageIndex, out int totalNumber) { OrderParam _orderParam = null; return FindPageList(pageSize, pageIndex, out totalNumber, _orderParam); } ///  /// 查找分页列表 ///  /// 每页记录数。必须大于1 /// 页码。首页从1开始,页码必须大于1 /// 总记录数 /// 排序键 /// 是否正序 ///  public IQueryable FindPageList(int pageSize, int pageIndex, out int totalNumber, OrderParam orderParam) { return FindPageList(pageSize, pageIndex, out totalNumber, (T)=> true, orderParam); } ///  /// 查找分页列表 ///  /// 每页记录数。必须大于1 /// 页码。首页从1开始,页码必须大于1 /// 总记录数 /// 查询表达式 public IQueryable FindPageList(int pageSize, int pageIndex, out int totalNumber, Expression> where) { OrderParam _param = null; return FindPageList(pageSize, pageIndex, out totalNumber, where, _param); } ///  /// 查找分页列表 ///  /// 每页记录数。 /// 页码。首页从1开始 /// 总记录数 /// 查询表达式 /// 排序【null-不设置】 ///  public IQueryable FindPageList(int pageSize, int pageIndex, out int totalNumber, Expression> where, OrderParam orderParam) { OrderParam[] _orderParams = null; if (orderParam != null) _orderParams = new OrderParam[] { orderParam }; return FindPageList(pageSize, pageIndex, out totalNumber, where, _orderParams); } ///  /// 查找分页列表 ///  /// 每页记录数。 /// 页码。首页从1开始 /// 总记录数 /// 查询表达式 /// 排序【null-不设置】 public IQueryable FindPageList(int pageSize, int pageIndex, out int totalNumber, Expression> where, OrderParam[] orderParams) { if (pageIndex < 1) pageIndex = 1; if (pageSize < 1) pageSize = 10; IQueryable _list = DbContext.Set().Where(where); var _orderParames = Expression.Parameter(typeof(T), "o"); if (orderParams != null && orderParams.Length > 0) { for (int i = 0; i < orderParams.Length; i++) { //根据属性名获取属性 var _property = typeof(T).GetProperty(orderParams[i].PropertyName); //创建一个访问属性的表达式 var _propertyAccess = Expression.MakeMemberAccess(_orderParames, _property); var _orderByExp = Expression.Lambda(_propertyAccess, _orderParames); string _orderName = orderParams[i].Method == OrderMethod.ASC ? "OrderBy" : "OrderByDescending"; MethodCallExpression resultExp = Expression.Call(typeof(Queryable), _orderName, new Type[] { typeof(T), _property.PropertyType }, _list.Expression, Expression.Quote(_orderByExp)); _list = _list.Provider.CreateQuery(resultExp); } } totalNumber = _list.Count(); return _list.Skip((pageIndex - 1) * pageIndex).Take(pageSize); } #endregion 

2、查找列表

基于分页列表同样的原因,对FindList方法也进行修改。

 //查找实体列表 #region FindList ///  /// 查找实体列表 ///  ///  public IQueryable FindList() { return DbContext.Set(); } ///  /// 查找实体列表 ///  /// 查询Lambda表达式 ///  public IQueryable FindList(Expression> where) { return DbContext.Set().Where(where); } ///  /// 查找实体列表 ///  /// 查询Lambda表达式 /// 获取的记录数量 ///  public IQueryable FindList(Expression> where, int number) { return DbContext.Set().Where(where).Take(number); } ///  /// 查找实体列表 ///  /// 查询Lambda表达式 /// 排序参数 ///  public IQueryable FindList(Expression> where, OrderParam orderParam) { return FindList(where, orderParam, 0); } ///  /// 查找实体列表 ///  /// 查询Lambda表达式 /// 排序参数 /// 获取的记录数量【0-不启用】 public IQueryable FindList(Expression> where, OrderParam orderParam, int number) { OrderParam[] _orderParams = null; if (orderParam != null) _orderParams = new OrderParam[] { orderParam }; return FindList(where, _orderParams, number); } ///  /// 查找实体列表 ///  /// 查询Lambda表达式 /// 排序参数 /// 获取的记录数量【0-不启用】 ///  public IQueryable FindList(Expression> where, OrderParam[] orderParams, int number) { var _list = DbContext.Set().Where(where); var _orderParames = Expression.Parameter(typeof(T), "o"); if (orderParams != null && orderParams.Length > 0) { for (int i = 0; i < orderParams.Length; i++) { //根据属性名获取属性 var _property = typeof(T).GetProperty(orderParams[i].PropertyName); //创建一个访问属性的表达式 var _propertyAccess = Expression.MakeMemberAccess(_orderParames, _property); var _orderByExp = Expression.Lambda(_propertyAccess, _orderParames); string _orderName = orderParams[i].Method == OrderMethod.ASC ? "OrderBy" : "OrderByDescending"; MethodCallExpression resultExp = Expression.Call(typeof(Queryable), _orderName, new Type[] { typeof(T), _property.PropertyType }, _list.Expression, Expression.Quote(_orderByExp)); _list = _list.Provider.CreateQuery(resultExp); } } if (number > 0) _list = _list.Take(number); return _list; 
                
                

-六神源码网