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 网站开发框架模型、数据存储以及业务逻辑的相关介绍,比之前两节的内容是不是更加丰富了,希望本文可以对大家的学习有所帮助。

时间: 2015-09-12

ASP.NET MVC5网站开发显示文章列表(九)

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

ASP.NET MVC5网站开发添加文章(八)

一.添加文章 1.KindEditor富文本编辑器 到官方网站http://kindeditor.net/down.php下载最新版本,解压后把代码复制到项目的Scripts文件夹下. 2.添加界面的显示. 在ArticleController中添加Add 方法 /// <summary> /// 添加文章 /// </summary> /// <returns>视图页面</returns> public ActionResult Add() { retur

一步步打造简单的MVC电商网站BooksStore(1)

一步步打造一个简单的 MVC 电商网站 - BooksStore(一) 本系列的 GitHub地址:https://github.com/liqingwen2015/Wen.BooksStore <一步步打造一个简单的 MVC 电商网站 - BooksStore(一)> <一步步打造一个简单的 MVC 电商网站 - BooksStore(二)> <一步步打造一个简单的 MVC 电商网站 - BooksStore(三)> <一步步打造一个简单的 MVC 电商网站 -

ASP.NET MVC5网站开发用户登录、注销(五)

一.创建ClaimsIdentity ClaimsIdentity(委托基于声明的标识)是在ASP.NET Identity身份认证系统的登录时要用到,我们在UserService中来生成它. 1.打开IBLL项目InterfaceUserService接口,添加接口方法ClaimsIdentity CreateIdentity(User user, string authenticationType); 2.打开BLL项目的UserService类,添加CreateIdentity方法的实现代

PHP MVC模式在网站架构中的实现分析

视图(View) "视图"主要指我们送到Web浏览器的最终结果??比如我们的脚本生成的HTML.当说到视图时,很多人想到的是模版,但是把模板方案叫做视图的正确性是值得怀疑的. 对视图来说,最重要的事情可能是它应该是"自我意识(self aware)"的,视图被渲染(render)时,视图的元素能意识到自己在更大框架中的角色. 以XML为例,可以说XML在被解析时,DOM API有着这样的认知??一个DOM树里的节点知道它在哪里和它包含了什么. (当一个XML文档中的

ASP.NET MVC5网站开发用户注册(四)

一.默认Web项目的更改 用户这部分还是自己做,所以删除自动生成的用户相关代码. 二.添加Member区域 在web项目上点右键 添加 区域Member. 添加Home控制器,选择MVC5控制器-空 我们给public ActionResult Index()添加一个视图,代码很简单就是显示下用户名 @{ ViewBag.Title = "会员中心"; } <h2>欢迎你!@User.Identity.Name </h2> 我们先运行一下,出错啦. 这是因为项目

CodeIgniter php mvc框架 中国网站

我们很高兴的宣布 CodeIgniter 1.6.2 版正式发布.本次发布包括超过 29 个 BUG 修复和 34 个功能补充和增强.这些内容包括:改善"Active Record"与事务性数据库的交互:引入一个常量文件:改善 Zip 类库:一个兼容性辅助函数:为文件辅助函数增加新的功能:从框架文件中删除 PHP 的关闭标记:还有许多其他的内容.更多细节请查看更改记录! 欢迎使用 CodeIgniter CodeIgniter 是一套给 PHP 网站开发者使用的应用程序开发框架和工具包

MVC4 网站发布(整理+部分问题收集和解决方案)

这部分是转载文章 在此标明出处,以前有文章是转的没标明的请谅解,因为有些已经无法找到出处,或者与其它原因. 如有冒犯请联系本人,或删除,或标明出处. 因为好的文章,以前只想收藏,但连接有时候会失效,所以现在碰到好的直接转到自己这里.  网站发布步骤: 1.打开你的VS2012网站项目,右键点击项目>菜单中 重新生成一下网站项目:再次点击右键>发布: 2.弹出网站发布设置面板,点击<新建..>,创建新的发布配置文件: 输入你自己定义的配置文件名: 3.点击下一步:在发布方法中选&qu

ASP.NET MVC5网站开发项目框架(二)

前几天算是开题了,关于怎么做自己想了很多,但毕竟没做过项目既不知道这些想法有无必要,也不知道能不能实现,不过邓爷爷说过"摸着石头过河"吧.这段时间看了一些博主的文章收获很大,特别是@kencery,依葫芦画瓢开写. 一.基本框架 还是先说下基本框架吧,一下子搞了7个项目看着挺乱的,我的理解是M.V.C 3者中,M是数据载体,V是用户要看的试图,C主要是协调控制与用户界面相关的操作,而数据的处理,数据库的的操作交给DAL.BLL来做.整个思路就是:View是用户看到的界面:Control

PHP发明人谈MVC和网站设计架构 貌似他不支持php用mvc

Q:越来越多Web 2.0网站走向应用平台,你认为打造这类平台的关键为何? A:简单来看,应用平台就是API,任何Ajax或 Web 2.0类型的网站,都是在应用平台上运用了API来创造出视觉介面的互动效果.例如Yahoo Mail,透过简单的Request呼叫,来读取後续的信件.打造这类网站,如何规画解决问题的方式,会决定了网站未来的扩充性(Scalability),而非效能决定网站的发展. Q:如何规画网站架构,才会具有扩充性? A:将一个网站应用,分成几十个独立小程式,前端透过 API提供

浅谈ASP.NET中多层架构

很多人对开发多层应用程序感到一定的困难.来看一个例子:对于一个只有一两个人的小公司,一个人可能同时担当老板.出纳.会计.市场.销售.开发等多项工作.而对于一个大公司,就会进行比较严密的分工,每个人只完成一部分工作,需要彼此配合才能保证正常运转.以前的开发程序就类似于一个小公司,从用户界面到数据库访问等所有功能都在一个页面内完成,这样的缺点有: 1. 开发起来比较困难,很难实现多人协作开发 2. 一旦数据库或规则有变,就可能要重新修改整个页面,加大维护成本 3. 因为所有功能都混合在一起,程序重用

浅谈mysql的索引设计原则以及常见索引的区别

索引定义:是一个单独的,存储在磁盘上的数据库结构,其包含着对数据表里所有记录的引用指针. 数据库索引的设计原则: 为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索引. 那么索引设计原则又是怎样的? 1.选择唯一性索引 唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录. 例如,学生表中学号是具有唯一性的字段.为该字段建立唯一性索引可以很快的确定某个学生的信息. 如果使用姓名的话,可能存在同名现象,从而降低查询速度. 2.为经常需要排序.分组和联合操

编码为GB2312网站让AJAX接收的数据显示支持中文

复制代码 代码如下: <script> var xmlHttp; var BrowerType="ie"; function createXML(){ try{ xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e){ try{ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); }catch(e2) { xmlHttp =f

从豆瓣网站设计谈网站重构

douban.com非常精巧的应用了div+css,并且通过色系的运用,最大限度减少图片等等方式既使得网站页面清新可人,而且可以最大限度的压缩了网页的大小,从而使得访问的效率得到了最大化. 第一次看douban.com,有一种拿着"读书"杂志在手上阅读的感觉,很素雅,好像还有那么点书香气息.被中国式网站强奸得都习以为常,以为网站也就这样而且也只能这样,无疑好多人第一次看到douban.com的时候都会被他的网站的简洁所触动,都会感觉眼前一亮!为什么会这样呢,于是有些想法,来看看doub

浅谈关于JavaScript API设计的一些建议和准则

设计是一个很普遍的概念,一般是可以理解为为即将做的某件事先形成一个计划或框架. (牛津英语词典)中,设计是一种将艺术,体系,硬件或者更多的东西编织到一块的主线.软件设计,特别是作为软件设计的次类的API设计,也是一样的.但是API设计常常很少关注软件发展,因为为其他程序员写代码的重要性要次于应用UI设计和最终用户体验. 但是API设计,作为我们自己写的库中提供的公共接口,能够向调用我们代码的开发者表现出我们库的一些特点和功能,所以API设计和UI设计一样重要.事实上,两者都是为应用可以提供更好的

大型网站设计注意事项大全

1.HTML静态化 其实大家都知道,效率最高.消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法.但是对于大量内容并且频繁更新的网站,我们无法全部手动去挨个实现,于是出现了我们常见的信息发布系统CMS,像我们常访问的各个门户站点的新闻频道,甚至他们的其他频道,都是通过信息发布系统来管理和实现的,信息发布系统可以实现最简单的信息录入自动生成静态页面,还能具备频道管理.权限管理.自动抓取等功能,对于一个大型网站来说,拥有一

网站设计应注意的25条有利于排名的建议

第一条:网站优化最重要的是网站内容要准确定位客户,这一点是网站是否能吸引您真正期望的访问者的直接因素. 第二条:精心选择和网站主题及所瞄准的时常相关的关键字. 第三条:尽量在网站内容中利用选择的关键字,值得注意的是,关键字尽量出现在内容的前面部分. 第四条:网站的标题中一定要包含您认为最为重要的关键字. 第五条:在头部标记中尽量运用关键字,将帮助网站在基于该关键字在搜索结果中的排名. 第六条:尽量为图像加上ALT标记,在该标记中包含必要的关键字. 第七条:千万别让关键字的颜色和网页背景颜色相同,

网站设计中25条有利于排名的建议

第一条:网站优化最重要的是网站内容要准确定位客户,这一点是网站是否能吸引您真正期望的访问者的直接因素. 第二条:精心选择和网站主题及所瞄准的时常相关的关键字. 第三条:尽量在网站内容中利用选择的关键字,值得注意的是,关键字尽量出现在内容的前面部分. 第四条:网站的标题中一定要包含您认为最为重要的关键字. 第五条:在头部标记中尽量运用关键字,将帮助网站在基于该关键字在搜索结果中的排名. 第六条:尽量为图像加上ALT标记,在该标记中包含必要的关键字. 第七条:千万别让关键字的颜色和网页背景颜色相同,

浅谈Redis在微服务架构中的几种应用场景

本文介绍在SpringCloud中使用Redis作为Pub/Sub异步通信.缓存或主数据库和配置服务器的三种场景应用. Redis可以广泛用于微服务架构.它可能是您应用程序以多种不同方式利用的少数流行软件解决方案之一.根据要求,它可以充当主数据库,缓存或消息代理.虽然它也是一个键/值存储,但我们可以将它用作微服务体系结构中的配置服务器或发现服务器.虽然它通常被定义为内存中的数据结构,但我们也可以在持久模式下运行它. 这里我将向您展示一些使用Redis与Spring Boot和Spring Clo