ASP.NET MVC5 网站开发框架模型、数据存储、业务逻辑(三)_实用技巧

前面项目的层次和调用关系都说明了,关系如下图

采用三层架构的时候,研究过BLL层的必要性,觉得业务逻辑完全可以在controller里实现,没有必要单独做一个项目,另一个分层多了会影响性能。后来我还是把业务逻辑独立出来,原因如下:

  • 业务逻辑写进controller里代码看着比较混乱,时间久了代码容易理不清。
  • 在controller里直接写逻辑重复代码会不较多,开发效率低。
  • 分项目有利于代码重用,有时候可以直接拿到其他项目中稍作修改就可以用。

对于性能我觉得分层多了肯定会有影响,但是不会很大。现在硬件的更新速度远大于软件,对业务逻辑处理起来很轻松,多实例化几个类对性能影响不大。一般来说网站运行基本上是一个存数据库和取数据库的过程,业务逻辑还是比较少,只不过现在的网站使用的图片、动画更多,效果更加绚丽。我觉得网站的效率瓶颈主要出现在服务器的带宽、IO性能和存取数据库上。在代码方面能做的就是优化数据库的存取。对了一般项目来说,为了百分之几的运行效率远不如提高开发效率和更加容易的代码管理重要,能实现需求就好,运行效率是哪是大牛要做的事。

对IDAL、DAL、IBLL 、BLL这四个项目:

IDAL写一个Base接口,接口中固定几个数据库操作方法,其他接口都继承自这个接口;

DAL项目做个base类实现这个IDAL的base接口,其他类都继承自base类。

同样IBLL中也写一个Base接口,固定几个基本的操作方法,同样其他接口也继承自这个base接口

IBLL中也写一个base类来实现IBLL中的base接口,其他类继承自这个base类。

这里以对用户的操作来构建代码的基本模式:

一、模型
这里写三个模型类。打开Ninesk.Models分别添加User、UserGroup、UserConfig三个模型类。

1、用户模型—User类
用户模型或者叫账户模型,为什么这么说看下面代码

using System;
using System.ComponentModel.DataAnnotations;

namespace Ninesky.Models
{
 /// <summary>
 /// 用户模型
 /// <remarks>
 /// 创建:2014.02.02<br />
 /// 修改:2014.02.05
 /// </remarks>
 /// </summary>
 public class User
 {
  [Key]
  public int UserID { get; set; }

  /// <summary>
  /// 用户名
  /// </summary>
  [Required(ErrorMessage="必填")]
  [StringLength(20,MinimumLength=4,ErrorMessage="{1}到{0}个字符")]
  [Display(Name="用户名")]
  public string UserName { get; set; }

  /// <summary>
  /// 用户组ID
  /// </summary>
  [Required(ErrorMessage = "必填")]
  [Display(Name = "用户组ID")]
  public int GroupID { get; set; }

  /// <summary>
  /// 显示名
  /// </summary>
  [Required(ErrorMessage = "必填")]
  [StringLength(20, MinimumLength = 2, ErrorMessage = "{1}到{0}个字符")]
  [Display(Name = "显示名")]
  public string DisplayName { get; set; }

  /// <summary>
  /// 密码
  /// </summary>
  [Required(ErrorMessage = "必填")]
  [Display(Name = "密码")]
  [DataType(DataType.Password)]
  public string Password { get; set; }

  /// <summary>
  /// 邮箱
  /// </summary>
  [Required(ErrorMessage = "必填")]
  [Display(Name = "邮箱")]
  [DataType(DataType.EmailAddress)]
  public string Email { get; set; }

  /// <summary>
  /// 用户状态<br />
  /// 0正常,1锁定,2未通过邮件验证,3未通过管理员
  /// </summary>
  public int Status { get; set; }

  /// <summary>
  /// 注册时间
  /// </summary>
  public DateTime RegistrationTime { get; set; }

  /// <summary>
  /// 上次登陆时间
  /// </summary>
  public DateTime LoginTime { get; set; }

  /// <summary>
  /// 上次登陆IP
  /// </summary>
  public DateTime LoginIP { get; set; }

  public virtual UserGroup Group { get; set; }

 }
}

这个模型类中只包含用户名、密码、用户组、显示名、邮箱等属性,纯粹是基本的账户信息,目的是让用户注册的时候尽可能的少填信息。其他信息如果需要可以再写新类与账户进行关联,用户需要的时候登录后再进行补填(如:资本资料、个人信息、联系方式等。这里先不考虑这些)。这里的显示名根据需要可以做昵称、真实姓名等来使用。

2、用户组模型—UserGroup类
这个类注意下GroupType,这个用来对用户组进行一下分类的,方便管理,其实没什么特别的意义。我的想法是普通类型就放普通的注册用户的组,如果大的网站允许用户升级的话,限定在这个类型的用户组内。特权组可以放一些vip之类的用户组,需要管理员给予,区别普通用户组,但又没有管理权。管理类型的用户组需要后台管理员给予,可以对文章、评论、咨询进行管理。

using System.ComponentModel.DataAnnotations;

namespace Ninesky.Models
{
 /// <summary>
 /// 用户组
 /// <remarks>
 /// 创建:2014.02.02
 /// 修改:2014.02.08
 /// </remarks>
 /// </summary>
 public class UserGroup
 {
  [Key]
  public int GroupID { get; set; }

  /// <summary>
  /// 名称
  /// </summary>
  [Required(ErrorMessage="必填")]
  [StringLength(20, MinimumLength = 2, ErrorMessage = "{1}到{0}个字")]
  [Display(Name="名称")]
  public string Name { get; set; }

  /// <summary>
  /// 用户组类型<br />
  /// 0普通类型(普通注册用户),1特权类型(像VIP之类的类型),3管理类型(管理权限的类型)
  /// </summary>
  [Required(ErrorMessage = "必填")]
  [Display(Name = "用户组类型")]
  public int GroupType { get; set; }

  /// <summary>
  /// 说明
  /// </summary>
  [Required(ErrorMessage = "必填")]
  [StringLength(50, ErrorMessage = "少于{0}个字")]
  [Display(Name = "说明")]
  public string Description { get; set; }
 }
}

3、用户配置模型类—UserConfig类
这个类是一些用户配置信息(暂时只考虑了注册设置),在后台管理员处进行设置。

using System.ComponentModel.DataAnnotations;

namespace Ninesky.Models
{
 /// <summary>
 /// 用户配置
 /// <remarks>
 /// 创建:2014.02.06
 /// </remarks>
 /// </summary>
 public class UserConfig
 {
  [Key]
  public int ConfigID { get; set; }

  /// <summary>
  /// 启用注册
  /// </summary>
  [Display(Name = "启用注册")]
  [Required(ErrorMessage="必填")]
  public bool Enabled { get; set; }

  /// <summary>
  /// 禁止使用的用户名<br />
  /// 用户名之间用“|”隔开
  /// </summary>
  [Display(Name = "禁止使用的用户名")]
  public string ProhibitUserName { get; set; }

  /// <summary>
  /// 启用管理员验证
  /// </summary>
  [Display(Name = "启用管理员验证")]
  [Required(ErrorMessage = "必填")]
  public bool EnableAdminVerify { get; set; }

  /// <summary>
  /// 启用邮件验证
  /// </summary>
  [Display(Name = "启用邮件验证")]
  [Required(ErrorMessage = "必填")]
  public bool EnableEmailVerify { get; set; }

  /// <summary>
  /// 默认用户组Id
  /// </summary>
  [Display(Name = "默认用户组Id")]
  [Required(ErrorMessage = "必填")]
  public int DefaultGroupId { get; set; }
 }
}

二、数据存储层
数据存储层负责与数据库打交道,由于使用了接口产生了两个项目DAL和IDAL。IDAL是接口项目,DAL是接口的实现项目。

在与数据库的方便有一些共同的操作,像添加、修改、删除、查询等。不想在实际写代码的时候在用户类写一遍这些东西,用户组类再写一遍、以后文章、评论都再重复写这些代码。怎么办,弄个基类。以后其他类从基类继承就把这些公共方法继承过来了。

1、IDAL项目
首先打开IDAL项目,添加类InterfaceBaseRepository,代码如下。

using System;
using System.Linq;
using System.Linq.Expressions;

namespace Ninesky.IDAL
{
 /// <summary>
 /// 接口基类
 /// <remarks>创建:2014.02.03 <br />
 /// 修改:2014.02.09</remarks>
 /// </summary>
 /// <typeparam name="T">类型</typeparam>
 public interface InterfaceBaseRepository<T>
 {
  /// <summary>
  /// 添加
  /// </summary>
  /// <param name="entity">数据实体</param>
  /// <returns>添加后的数据实体</returns>
  T Add(T entity);

  /// <summary>
  /// 查询记录数
  /// </summary>
  /// <param name="predicate">条件表达式</param>
  /// <returns>记录数</returns>
  int Count(Expression<Func<T, bool>> predicate);

  /// <summary>
  /// 更新
  /// </summary>
  /// <param name="entity">数据实体</param>
  /// <returns>是否成功</returns>
  bool Update(T entity);

  /// <summary>
  /// 删除
  /// </summary>
  /// <param name="entity">数据实体</param>
  /// <returns>是否成功</returns>
  bool Delete(T entity);

  /// <summary>
  /// 是否存在
  /// </summary>
  /// <param name="anyLambda">查询表达式</param>
  /// <returns>布尔值</returns>
  bool Exist(Expression<Func<T, bool>> anyLambda);

  /// <summary>
  /// 查询数据
  /// </summary>
  /// <param name="whereLambda">查询表达式</param>
  /// <returns>实体</returns>
  T Find(Expression<Func<T, bool>> whereLambda);

  /// <summary>
  /// 查找数据列表
  /// </summary>
  /// <typeparam name="S">排序</typeparam>
  /// <param name="whereLamdba">查询表达式</param>
  /// <param name="isAsc">是否升序</param>
  /// <param name="orderLamdba">排序表达式</param>
  /// <returns></returns>
  IQueryable<T> FindList<S>(Expression<Func<T, bool>> whereLamdba, bool isAsc, Expression<Func<T, S>> orderLamdba);

  /// <summary>
  /// 查找分页数据列表
  /// </summary>
  /// <typeparam name="S">排序</typeparam>
  /// <param name="pageIndex">当前页</param>
  /// <param name="pageSize">每页记录数</param>
  /// <param name="totalRecord">总记录数</param>
  /// <param name="whereLamdba">查询表达式</param>
  /// <param name="isAsc">是否升序</param>
  /// <param name="orderLamdba">排序表达式</param>
  /// <returns></returns>
  IQueryable<T> FindPageList<S>(int pageIndex, int pageSize, out int totalRecord, Expression<Func<T, bool>> whereLamdba, bool isAsc, Expression<Func<T, S>> orderLamdba);

 }
}

这里定义了增、删、改、判断存在、返回模型的查询、返回集合的查询,返回分页集合的查询7个公共方法。这几个方法基本满足一般需要,特殊的方法在继承的时候再添加。
还使用了泛型,在继承的时候传入实体类型就可以直接继承这些方法了。具体看下InterfaceUserRepository接口就清楚了。

using Ninesky.Models;
namespace Ninesky.IDAL
{
 /// <summary>
 /// 用户接口
 /// <remarks>创建:2014.02.03</remarks>
 /// </summary>
 public interface InterfaceUserRepository:InterfaceBaseRepository<User>
 {
 }
}

简单吧,继承自InterfaceBaseRepository接口并传入实体类User就行了。我们在类视图中看下,是不是继承了基类的接口。

2、DAL项目
DAL项目是对IDAL项目接口的实现,项目中要创建DbContext类,对于DbContext类很多人讨论过它对数据库存取的效率,MSDN中说其是轻量的, 创建不需要很大开销,它也不是线程安全的对象,并且具有数据容器的性质(跟踪),因此很多人认为不应该将其静态化、单例化。但是对用户的单次请求来说实现DbContext唯一是合理的。 先看代码吧,非常简单。

using Ninesky.Models;
using System.Data.Entity;

namespace Ninesky.DAL
{
 /// <summary>
 /// 数据上下文
 /// <remarks>创建:2014.02.03</remarks>
 /// </summary>
 public class NineskyDbContext:DbContext
 {
  public DbSet<User> Users { get; set; }
  public DbSet<UserGroup> UserGroups { get; set; }
  public DbSet<UserConfig> UserConfig { get; set; }
  public NineskyDbContext()
   : base("DefaultConnection")
  {
  }
 }
}

下面创建一个BaseRepository类,继承自InterfaceBaseRepository并实现类其接口的方法。

using Ninesky.IDAL;
using System;
using System.Linq;
using System.Linq.Expressions;

namespace Ninesky.DAL
{
 /// <summary>
 /// 仓储基类
 /// <remarks>创建:2014.02.03</remarks>
 /// </summary>
 public class BaseRepository<T>: InterfaceBaseRepository<T> where T : class
 {
  protected NineskyDbContext nContext = ContextFactory.GetCurrentContext();

  public T Add(T entity)
  {
   nContext.Entry<T>(entity).State = System.Data.Entity.EntityState.Added;
   nContext.SaveChanges();
   return entity;
  }

  public int Count(Expression<Func<T, bool>> predicate)
  {
   return nContext.Set<T>().Count(predicate);
  }

  public bool Update(T entity)
  {
   nContext.Set<T>().Attach(entity);
   nContext.Entry<T>(entity).State = System.Data.Entity.EntityState.Modified;
   return nContext.SaveChanges() > 0;
  }

  public bool Delete(T entity)
  {
   nContext.Set<T>().Attach(entity);
   nContext.Entry<T>(entity).State = System.Data.Entity.EntityState.Deleted;
   return nContext.SaveChanges() > 0;
  }

  public bool Exist(Expression<Func<T, bool>> anyLambda)
  {
   return nContext.Set<T>().Any(anyLambda);
  }

  public T Find(Expression<Func<T, bool>> whereLambda)
  {
   T _entity = nContext.Set<T>().FirstOrDefault<T>(whereLambda);
   return _entity;
  }

  public IQueryable<T> FindList<S>(Expression<Func<T, bool>> whereLamdba, bool isAsc, Expression<Func<T, S>> orderLamdba)
  {
   var _list = nContext.Set<T>().Where<T>(whereLamdba);
   if (isAsc) _list = _list.OrderBy<T, S>(orderLamdba);
   else _list = _list.OrderByDescending<T, S>(orderLamdba);
   return _list;
  }

  public IQueryable<T> FindPageList<S>(int pageIndex, int pageSize, out int totalRecord, Expression<Func<T, bool>> whereLamdba, bool isAsc, Expression<Func<T, S>> orderLamdba)
  {
   var _list = nContext.Set<T>().Where<T>(whereLamdba);
   totalRecord = _list.Count();
   if (isAsc) _list = _list.OrderBy<T, S>(orderLamdba).Skip<T>((pageIndex - 1) * pageSize).Take<T>(pageSize);
   else _list = _list.OrderByDescending<T, S>(orderLamdba).Skip<T>((pageIndex - 1) * pageSize).Take<T>(pageSize);
   return _list;
  }
 }
}

代码中都是对数据库的操作。比较有看头的是这句protected NineskyDbContext nContext = ContextFactory.GetCurrentContext();

ContextFactory是一个简单工厂类,GetCurrentContext()是一个静态函数。利用简单工厂获取请求内的当前DbContext,也就是请求内的DbContext单例。先添加一个工厂类ContextFactory

using System.Data.Entity;
using System.Runtime.Remoting.Messaging;

namespace Ninesky.DAL
{
 /// <summary>
 /// 上下文简单工厂
 /// <remarks>
 /// 创建:2014.02.05
 /// </remarks>
 /// </summary>
 public class ContextFactory
 {

  /// <summary>
  /// 获取当前数据上下文
  /// </summary>
  /// <returns></returns>
  public static NineskyDbContext GetCurrentContext()
  {
   NineskyDbContext _nContext = CallContext.GetData("NineskyContext") as NineskyDbContext;
   if (_nContext == null)
   {
    _nContext = new NineskyDbContext();
    CallContext.SetData("NineskyContext", _nContext);
   }
   return _nContext;
  }
 }
}

这里是先在CallContext中获取NineskyContext,如果为空则初始化一个NineskyContext,如果存在则直接返回。看CallContext,MSDN中讲CallContext提供对每个逻辑执行线程都唯一的数据槽,而在WEB程序里,每一个请求恰巧就是一个逻辑线程所以可以使用CallContext来实现单个请求之内的DbContext单例。

下面添加具体的仓储代码。

在DAL中再添加一个UserRepository类,继承自BaseRepository和InterfaceUserRepository。目的是继承自BaseRepository类,实现InterfaceUserRepositor接口。

using Ninesky.IDAL;
using Ninesky.Models;
using System.Linq;

namespace Ninesky.DAL
{
 /// <summary>
 /// 用户仓库
 /// <remarks>创建:2014.02.03</remarks>
 /// </summary>
 class UserRepository: BaseRepository<User>, InterfaceUserRepository
 {
 }
}

UserRepository就直接继承了基类中的方法,基类中的方法能满足绝大部分需要,UserRepository就不用再增加函数了,其他Repository类都类似,不在贴代码了。

这里我们在建一个Repository工厂,用来返回项目中的所有Repository类。

using Ninesky.IDAL;

namespace Ninesky.DAL
{
 /// <summary>
 /// 简单工厂?
 /// <remarks>创建:2014.02.03</remarks>
 /// </summary>
 public static class RepositoryFactory
 {
  /// <summary>
  /// 用户仓储
  /// </summary>
  public static InterfaceUserRepository UserRepository { get { return new UserRepository(); } }
 }
}

以后在BLL中调用的时候就不用每次都写InterfaceUserRepository _iUserRsy = new  UserRepository()了,直接写成InterfaceUserRepository _iUserRsy = RepositoryFactory.UserRepository这个东西的好处就是,以后在DAL项目中实现InterfaceUserRepository接口的类需要修改时我们可以直接创建个新类,然后RepositoryFactory类中让UserRepository属性返回新类就行了。

3、IBLL项目
IBLL是业务逻辑层的接口,业务逻辑层对数据库的操作上基本还是增、删、改。同样写一个基接口把这三个操作写进去,这里与IDAL思路类似。

namespace Ninesky.IBLL
{
 /// <summary>
 /// 接口基类
 /// <remarks>创建:2014.02.03</remarks>
 /// </summary>
 public interface InterfaceBaseService<T> where T : class
 {
  /// <summary>
  /// 添加
  /// </summary>
  /// <param name="entity">数据实体</param>
  /// <returns>添加后的数据实体</returns>
  T Add(T entity);

  /// <summary>
  /// 更新
  /// </summary>
  /// <param name="entity">数据实体</param>
  /// <returns>是否成功</returns>
  bool Update(T entity);

  /// <summary>
  /// 删除
  /// </summary>
  /// <param name="entity">数据实体</param>
  /// <returns>是否成功</returns>
  bool Delete(T entity);
 }
}

在添加一个InterfaceUserService接口,继承自InterfaceBaseService。根据需要在接口中又添加了几个方法。在这里对Find方法的名称进行统一,凡是返回实体类的名称为Find()或FindByXXX(),返回一组数据的方法名称为FindList()或FindXXXList,分页的名称格式为FindPageList()或FindxxxPageList()

using Ninesky.Models;
using System.Linq;

namespace Ninesky.IBLL
{
 /// <summary>
 /// 用户相关接口
 /// <remarks>
 /// 创建:2014.02.09
 /// </remarks>
 /// </summary>
 public interface InterfaceUserService:InterfaceBaseService<User>
 {

  /// <summary>
  /// 用户是否存在
  /// </summary>
  /// <param name="userName">用户名</param>
  /// <returns>布尔值</returns>
  bool Exist(string userName);

  /// <summary>
  /// 查找用户
  /// </summary>
  /// <param name="userID">用户ID</param>
  /// <returns></returns>
  User Find(int userID);

  /// <summary>
  /// 查找用户
  /// </summary>
  /// <param name="userName">用户名</param>
  /// <returns></returns>
  User Find(string userName);

  /// <summary>
  /// 用户列表
  /// </summary>
  /// <param name="pageIndex">页码数</param>
  /// <param name="pageSize">每页记录数</param>
  /// <param name="totalRecord">总记录数</param>
  /// <param name="order">排序:0-ID升序(默认),1ID降序,2注册时间升序,3注册时间降序,4登录时间升序,5登录时间降序</param>
  /// <returns></returns>
  IQueryable<User> FindPageList(int pageIndex, int pageSize, out int totalRecord,int order);
 }
}

4、BLL项目
BLL项目中要实现InterfaceUserService接口的方法,先添加BaseService的

using Ninesky.IBLL;
using Ninesky.IDAL;
namespace Ninesky.BLL
{
 /// <summary>
 /// 服务基类
 /// <remarks>创建:2014.02.03</remarks>
 /// </summary>
 public abstract class BaseService<T> : InterfaceBaseService<T> where T : class
 {
  protected InterfaceBaseRepository<T> CurrentRepository { get; set; }

  public BaseService(InterfaceBaseRepository<T> currentRepository) { CurrentRepository = currentRepository; }

  public T Add(T entity) { return CurrentRepository.Add(entity); }

  public bool Update(T entity) { return CurrentRepository.Update(entity); }

  public bool Delete(T entity) { return CurrentRepository.Delete(entity); }
 }
}

这个类的构造函数中要传入一个参数就是currentRepository 这个在继承的时候进行传入。这里还是看用户类。

using Ninesky.DAL;
using Ninesky.IBLL;
using Ninesky.Models;
using System.Linq;

namespace Ninesky.BLL
{
 /// <summary>
 /// 用户服务类
 /// <remarks>
 /// 创建:2014.02.12
 /// </remarks>
 /// </summary>
 public class UserService:BaseService<User>,InterfaceUserService
 {
  public UserService() : base(RepositoryFactory.UserRepository) { }

  public bool Exist(string userName) { return CurrentRepository.Exist(u => u.UserName == userName);}

  public User Find(int userID) { return CurrentRepository.Find(u => u.UserID == userID); }

  public User Find(string userName) { return CurrentRepository.Find(u => u.UserName == userName); }

  public IQueryable<User> FindPageList(int pageIndex, int pageSize, out int totalRecord, int order)
  {
   switch(order)
   {
    case 0: return CurrentRepository.FindPageList(pageIndex, pageSize, out totalRecord, u => true, true, u => u.UserID);
    case 1: return CurrentRepository.FindPageList(pageIndex, pageSize, out totalRecord, u => true, false, u => u.UserID);
    case 2: return CurrentRepository.FindPageList(pageIndex, pageSize, out totalRecord, u => true, true, u => u.RegistrationTime);
    case 3: return CurrentRepository.FindPageList(pageIndex, pageSize, out totalRecord, u => true, false, u => u.RegistrationTime);
    case 4: return CurrentRepository.FindPageList(pageIndex, pageSize, out totalRecord, u => true, true, u => u.LoginTime);
    case 5: return CurrentRepository.FindPageList(pageIndex, pageSize, out totalRecord, u => true, false, u => u.LoginTime);
    default: return CurrentRepository.FindPageList(pageIndex, pageSize, out totalRecord, u => true, true, u => u.UserID);
   }

  }
 }
}

上面这个FindPageList代码太累赘了,一时还没想到好方法。

5、总结
今天写到这里还是在想项目间的调用实现,写了两个base接口、两个base类,以后其他的类都从它们继承,写法都很类似。下次可以开始做界面了,在Ninesky.Web项目中基本上是通过IBLL,BLL跟数据进行打交道了。

 ===================================================

FindPageList() 这个排序的方法确实不太通用,代码修改如下:

1、接口 InterfaceBaseRepository

修改两个接口方法如图红框部分。

image

2、BaseRepository类

添加OrderBy方法,代码如下:

/// <summary>
  /// 排序
  /// </summary>
  /// <typeparam name="T">类型</typeparam>
  /// <param name="source">原IQueryable</param>
  /// <param name="propertyName">排序属性名</param>
  /// <param name="isAsc">是否正序</param>
  /// <returns>排序后的IQueryable<T></returns>
  private IQueryable<T> OrderBy(IQueryable<T> source, string propertyName, bool isAsc)
  {
   if (source == null) throw new ArgumentNullException("source", "不能为空");
   if (string.IsNullOrEmpty(propertyName)) return source;
   var _parameter = Expression.Parameter(source.ElementType);
   var _property = Expression.Property(_parameter, propertyName);
   if (_property == null) throw new ArgumentNullException("propertyName", "属性不存在");
   var _lambda = Expression.Lambda(_property, _parameter);
   var _methodName = isAsc ? "OrderBy" : "OrderByDescending";
   var _resultExpression = Expression.Call(typeof(Queryable), _methodName, new Type[] { source.ElementType, _property.Type }, source.Expression, Expression.Quote(_lambda));
   return source.Provider.CreateQuery<T>(_resultExpression);
  }
修改FindList和FindPageList方法,修改下图

image

3、修改UserService的FindPageList方法

修改后的代码如下:

public IQueryable<User> FindPageList(int pageIndex, int pageSize, out int totalRecord, int order)
  {
   bool _isAsc = true;
   string _orderName = string.Empty;
   switch(order)
   {
    case 0:
     _isAsc = true;
     _orderName = "UserID";
     break;
    case 1:
     _isAsc = false;
     _orderName = "UserID";
     break;
    case 2:
     _isAsc = true;
     _orderName = "RegistrationTime";
     break;
    case 3:
     _isAsc = false;
     _orderName = "RegistrationTime";
     break;
    case 4:
     _isAsc = true;
     _orderName = "LoginTime";
     break;
    case 5: _isAsc = false;
     _orderName = "LoginTime";
     break;
    default:
     _isAsc = false;
     _orderName = "UserID";
     break;
   }
   return CurrentRepository.FindPageList(pageIndex, pageSize, out totalRecord, u => true, _orderName, _isAsc);
  }

以上就是ASP.NET MVC5 网站开发框架模型、数据存储以及业务逻辑的相关介绍,比之前两节的内容是不是更加丰富了,希望本文可以对大家的学习有所帮助。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索asp.net
, 数据存储
, 网站开发
, mvc5
, 业务逻辑
框架模型
,以便于您获取更多的相关知识。

时间: 2024-07-29 17:52:44

ASP.NET MVC5 网站开发框架模型、数据存储、业务逻辑(三)_实用技巧的相关文章

ASP.NET MVC5网站开发咨询管理的架构(十一)_实用技巧

一.总体说明 1.实现功能 2.类图 由于文章部分把大部分类都是实现了,这里仅多了一个Consultation类. 二.创建咨询模型类 在Ninesky.Models项目添加类Consultation(咨询模型),该模型跟Article类似都是CommonModel的扩展.1.添加Consultation类. using System; using System.ComponentModel.DataAnnotations; namespace Ninesky.Models { /// <sum

ASP.NET MVC5网站开发显示文章列表(九)_实用技巧

老习惯,先上个效果图: 1.在IBLL在InterfaceCommonModelService接口中添加获取公共模型列表的方法 首先排序方法 /// <summary> /// 排序 /// </summary> /// <param name="entitys">数据实体集</param> /// <param name="roderCode">排序代码[默认:ID降序]</param> //

ASP.NET MVC5网站开发之总体概述(一)_实用技巧

由于前几次都没能写完,这次年底总算有自由时间了,又想继续捣鼓一下.于是下载了VS 2015专业版(不知为什么我特别钟爱专业版,而不喜欢企业版).由于以前的教训,我这次决定写一个极简的Deom,简到什么程度呢?简单到只实现添加.修改栏目,用户登录后可以添加管理文章.管理员登陆后可以修改网站设置(也就标题.版权信息等)这些功能.为了避免以前大家经常搞不清哪个是最新的代码的情况,这次我准备把代码直接发布到Codeplex.com上做个代码开源,到时候大家直接去Codeplex.com下载最新代码就行了

ASP.NET MVC5网站开发文章管理架构(七)_实用技巧

一.总体说明 先看一下文章管理设想要实现的功能: 再看一下类图 这里Category是栏目:CommonModel是公共模型:Article是文章:Attachment是附件: CommonModel是内容管理这块抽取出来的公共部分,像文章,咨询甚至产品都有一些共同的内容这里把它单独提取出来作为一个类.CommonModel可能包含一片文章,包含一组附件,包含一系列评论,他们之间的关系类图中已经表示出来.  二.搭建架构 这个顺序根以前一样 1.IDAL 在IDAL添加接口InterfaceCo

ASP.NET中RadioButtonList绑定后台数据后触发点击事件_实用技巧

本文实例为大家分享了RadioButtonList绑定后台数据,触发点击事件的方法 首先前台页面放置一个RadioButtonList 控件 <asp:RadioButtonList runat="server" ID="RadioButtonList1" BorderStyle="None" RepeatColumns="3" CssClass="" RepeatLayout="Flow&

ASP.NET MVC 数据验证及相关内容_实用技巧

一.数据验证 数据验证的步骤在模型类中添加与验证相关的特性标记在客户端导入与验证相关的js文件和css文件使用与验证相关的Html辅助方法在服务器端判断是否通过服务器端验证常用的验证标记 Required:非空验证StringLength:验证字符串的长度RegularExpression:正则表达式验证Compare:比较两个字段的值是否相等Range:范围验证Remote:服务器验证(需要在controller中编写返回值为JsonResult的Action)自定义验证标记与验证相关的js文

ASP.NET网站导航及导航控件如何使用_实用技巧

网站导航? 传统的网站导航需要我们在是在页面上弄超链接的方式来实现的,在页面修改或移动的的时候需要一一在每个页中都要进行修改,这样会很麻烦. 在网站中建立网站地图,也就是把所有的链接地址放在一个专门的文件中进行统一管理,这样就很方面的进行管理. 怎么弄网站导航?怎么做? 需要在VS中新建网站地图文件,再把网站地图文件与我们想要的导航控件相关联,这样就可以实现导航的效果了,我们要更改某个地址,就直接在站点地图.siteMap文件中更改就行了. vs中如何添加网站地图? 在vs中新建项中选择"站点地

asp.net不同页面间数据传递的多种方法_实用技巧

1. Get(即使用QueryString显式传递)方式:在url后面跟参数.特点:简单.方便.缺点:字符串长度最长为255个字符:数据泄漏在url中.适用数据:简单.少量.关键的数据.适用范围:传递给自己.传递给另一个目标页面:常用于2个页面间传递数据.用法:例如:url后加?UserID=-,跳转到目标页面,目标页面在伺服端可用Request.QueryString["InputText"]获取其指定参数值. 2. Post方式:通用的方式.利用form提交.特点:最常用的方法.常

用 Asp.Net 建立一个在线 RSS 新闻聚合器的方法_实用技巧

随着办公室和家庭上网在线时间的延长,以及 Web 站点和可访问的互联网应用程序呈持续爆炸性增长,应用程序之间能数据共享变得越来越重要.在异构平台之间共享数据需要一种平台中立的数据格式,这种数据格式要求能易于通过标准的互联网协议来传输,而这正是XML的用武之地.因为XML文件本质上只是一个文本文件,其编码格式众所周知,而且现有的XML解析器能为所有主流编程语言所用,所以XML数据能被任何平台轻松使用.  Web 网站聚合就是一种使用 XML 来共享数据的范例,在新闻站点和网志中经常可以看到.采用