濮阳杆衣贸易有限公司

主頁(yè) > 知識(shí)庫(kù) > ASP.NET MVC5 網(wǎng)站開(kāi)發(fā)框架模型、數(shù)據(jù)存儲(chǔ)、業(yè)務(wù)邏輯(三)

ASP.NET MVC5 網(wǎng)站開(kāi)發(fā)框架模型、數(shù)據(jù)存儲(chǔ)、業(yè)務(wù)邏輯(三)

熱門(mén)標(biāo)簽:西寧電銷(xiāo)外呼系統(tǒng)公司 上海市三維地圖標(biāo)注 辦公用地圖標(biāo)注網(wǎng)點(diǎn)怎么操作 云南外呼系統(tǒng)代理 聊城智能電銷(xiāo)機(jī)器人電話 南昌自動(dòng)外呼系統(tǒng)線路 安陸市地圖標(biāo)注app 寧德防封版電銷(xiāo)卡 海東防封電銷(xiāo)卡

前面項(xiàng)目的層次和調(diào)用關(guān)系都說(shuō)明了,關(guān)系如下圖

采用三層架構(gòu)的時(shí)候,研究過(guò)BLL層的必要性,覺(jué)得業(yè)務(wù)邏輯完全可以在controller里實(shí)現(xiàn),沒(méi)有必要單獨(dú)做一個(gè)項(xiàng)目,另一個(gè)分層多了會(huì)影響性能。后來(lái)我還是把業(yè)務(wù)邏輯獨(dú)立出來(lái),原因如下:

  • 業(yè)務(wù)邏輯寫(xiě)進(jìn)controller里代碼看著比較混亂,時(shí)間久了代碼容易理不清。
  • 在controller里直接寫(xiě)邏輯重復(fù)代碼會(huì)不較多,開(kāi)發(fā)效率低。
  • 分項(xiàng)目有利于代碼重用,有時(shí)候可以直接拿到其他項(xiàng)目中稍作修改就可以用。

對(duì)于性能我覺(jué)得分層多了肯定會(huì)有影響,但是不會(huì)很大?,F(xiàn)在硬件的更新速度遠(yuǎn)大于軟件,對(duì)業(yè)務(wù)邏輯處理起來(lái)很輕松,多實(shí)例化幾個(gè)類(lèi)對(duì)性能影響不大。一般來(lái)說(shuō)網(wǎng)站運(yùn)行基本上是一個(gè)存數(shù)據(jù)庫(kù)和取數(shù)據(jù)庫(kù)的過(guò)程,業(yè)務(wù)邏輯還是比較少,只不過(guò)現(xiàn)在的網(wǎng)站使用的圖片、動(dòng)畫(huà)更多,效果更加絢麗。我覺(jué)得網(wǎng)站的效率瓶頸主要出現(xiàn)在服務(wù)器的帶寬、IO性能和存取數(shù)據(jù)庫(kù)上。在代碼方面能做的就是優(yōu)化數(shù)據(jù)庫(kù)的存取。對(duì)了一般項(xiàng)目來(lái)說(shuō),為了百分之幾的運(yùn)行效率遠(yuǎn)不如提高開(kāi)發(fā)效率和更加容易的代碼管理重要,能實(shí)現(xiàn)需求就好,運(yùn)行效率是哪是大牛要做的事。

對(duì)IDAL、DAL、IBLL 、BLL這四個(gè)項(xiàng)目:

IDAL寫(xiě)一個(gè)Base接口,接口中固定幾個(gè)數(shù)據(jù)庫(kù)操作方法,其他接口都繼承自這個(gè)接口;

DAL項(xiàng)目做個(gè)base類(lèi)實(shí)現(xiàn)這個(gè)IDAL的base接口,其他類(lèi)都繼承自base類(lèi)。

同樣IBLL中也寫(xiě)一個(gè)Base接口,固定幾個(gè)基本的操作方法,同樣其他接口也繼承自這個(gè)base接口

IBLL中也寫(xiě)一個(gè)base類(lèi)來(lái)實(shí)現(xiàn)IBLL中的base接口,其他類(lèi)繼承自這個(gè)base類(lèi)。

這里以對(duì)用戶的操作來(lái)構(gòu)建代碼的基本模式:

一、模型
這里寫(xiě)三個(gè)模型類(lèi)。打開(kāi)Ninesk.Models分別添加User、UserGroup、UserConfig三個(gè)模型類(lèi)。

1、用戶模型—User類(lèi)
用戶模型或者叫賬戶模型,為什么這么說(shuō)看下面代碼

using System;
using System.ComponentModel.DataAnnotations;

namespace Ninesky.Models
{
 /// summary>
 /// 用戶模型
 /// remarks>
 /// 創(chuàng)建:2014.02.02br />
 /// 修改: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}個(gè)字符")]
  [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}個(gè)字符")]
  [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>
  /// 用戶狀態(tài)br />
  /// 0正常,1鎖定,2未通過(guò)郵件驗(yàn)證,3未通過(guò)管理員
  /// /summary>
  public int Status { get; set; }

  /// summary>
  /// 注冊(cè)時(shí)間
  /// /summary>
  public DateTime RegistrationTime { get; set; }

  /// summary>
  /// 上次登陸時(shí)間
  /// /summary>
  public DateTime LoginTime { get; set; }

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

  public virtual UserGroup Group { get; set; }

 }
}

這個(gè)模型類(lèi)中只包含用戶名、密碼、用戶組、顯示名、郵箱等屬性,純粹是基本的賬戶信息,目的是讓用戶注冊(cè)的時(shí)候盡可能的少填信息。其他信息如果需要可以再寫(xiě)新類(lèi)與賬戶進(jìn)行關(guān)聯(lián),用戶需要的時(shí)候登錄后再進(jìn)行補(bǔ)填(如:資本資料、個(gè)人信息、聯(lián)系方式等。這里先不考慮這些)。這里的顯示名根據(jù)需要可以做昵稱(chēng)、真實(shí)姓名等來(lái)使用。

2、用戶組模型—UserGroup類(lèi)
這個(gè)類(lèi)注意下GroupType,這個(gè)用來(lái)對(duì)用戶組進(jìn)行一下分類(lèi)的,方便管理,其實(shí)沒(méi)什么特別的意義。我的想法是普通類(lèi)型就放普通的注冊(cè)用戶的組,如果大的網(wǎng)站允許用戶升級(jí)的話,限定在這個(gè)類(lèi)型的用戶組內(nèi)。特權(quán)組可以放一些vip之類(lèi)的用戶組,需要管理員給予,區(qū)別普通用戶組,但又沒(méi)有管理權(quán)。管理類(lèi)型的用戶組需要后臺(tái)管理員給予,可以對(duì)文章、評(píng)論、咨詢進(jìn)行管理。

using System.ComponentModel.DataAnnotations;

namespace Ninesky.Models
{
 /// summary>
 /// 用戶組
 /// remarks>
 /// 創(chuàng)建:2014.02.02
 /// 修改:2014.02.08
 /// /remarks>
 /// /summary>
 public class UserGroup
 {
  [Key]
  public int GroupID { get; set; }

  /// summary>
  /// 名稱(chēng)
  /// /summary>
  [Required(ErrorMessage="必填")]
  [StringLength(20, MinimumLength = 2, ErrorMessage = "{1}到{0}個(gè)字")]
  [Display(Name="名稱(chēng)")]
  public string Name { get; set; }

  /// summary>
  /// 用戶組類(lèi)型br />
  /// 0普通類(lèi)型(普通注冊(cè)用戶),1特權(quán)類(lèi)型(像VIP之類(lèi)的類(lèi)型),3管理類(lèi)型(管理權(quán)限的類(lèi)型)
  /// /summary>
  [Required(ErrorMessage = "必填")]
  [Display(Name = "用戶組類(lèi)型")]
  public int GroupType { get; set; }

  /// summary>
  /// 說(shuō)明
  /// /summary>
  [Required(ErrorMessage = "必填")]
  [StringLength(50, ErrorMessage = "少于{0}個(gè)字")]
  [Display(Name = "說(shuō)明")]
  public string Description { get; set; }
 }
}

3、用戶配置模型類(lèi)—UserConfig類(lèi)
這個(gè)類(lèi)是一些用戶配置信息(暫時(shí)只考慮了注冊(cè)設(shè)置),在后臺(tái)管理員處進(jìn)行設(shè)置。

using System.ComponentModel.DataAnnotations;

namespace Ninesky.Models
{
 /// summary>
 /// 用戶配置
 /// remarks>
 /// 創(chuàng)建:2014.02.06
 /// /remarks>
 /// /summary>
 public class UserConfig
 {
  [Key]
  public int ConfigID { get; set; }

  /// summary>
  /// 啟用注冊(cè)
  /// /summary>
  [Display(Name = "啟用注冊(cè)")]
  [Required(ErrorMessage="必填")]
  public bool Enabled { get; set; }

  /// summary>
  /// 禁止使用的用戶名br />
  /// 用戶名之間用“|”隔開(kāi)
  /// /summary>
  [Display(Name = "禁止使用的用戶名")]
  public string ProhibitUserName { get; set; }

  /// summary>
  /// 啟用管理員驗(yàn)證
  /// /summary>
  [Display(Name = "啟用管理員驗(yàn)證")]
  [Required(ErrorMessage = "必填")]
  public bool EnableAdminVerify { get; set; }

  /// summary>
  /// 啟用郵件驗(yàn)證
  /// /summary>
  [Display(Name = "啟用郵件驗(yàn)證")]
  [Required(ErrorMessage = "必填")]
  public bool EnableEmailVerify { get; set; }

  /// summary>
  /// 默認(rèn)用戶組Id
  /// /summary>
  [Display(Name = "默認(rèn)用戶組Id")]
  [Required(ErrorMessage = "必填")]
  public int DefaultGroupId { get; set; }
 }
}

二、數(shù)據(jù)存儲(chǔ)層
數(shù)據(jù)存儲(chǔ)層負(fù)責(zé)與數(shù)據(jù)庫(kù)打交道,由于使用了接口產(chǎn)生了兩個(gè)項(xiàng)目DAL和IDAL。IDAL是接口項(xiàng)目,DAL是接口的實(shí)現(xiàn)項(xiàng)目。

在與數(shù)據(jù)庫(kù)的方便有一些共同的操作,像添加、修改、刪除、查詢等。不想在實(shí)際寫(xiě)代碼的時(shí)候在用戶類(lèi)寫(xiě)一遍這些東西,用戶組類(lèi)再寫(xiě)一遍、以后文章、評(píng)論都再重復(fù)寫(xiě)這些代碼。怎么辦,弄個(gè)基類(lèi)。以后其他類(lèi)從基類(lèi)繼承就把這些公共方法繼承過(guò)來(lái)了。

1、IDAL項(xiàng)目
首先打開(kāi)IDAL項(xiàng)目,添加類(lèi)InterfaceBaseRepository,代碼如下。

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

namespace Ninesky.IDAL
{
 /// summary>
 /// 接口基類(lèi)
 /// remarks>創(chuàng)建:2014.02.03 br />
 /// 修改:2014.02.09/remarks>
 /// /summary>
 /// typeparam name="T">類(lèi)型/typeparam>
 public interface InterfaceBaseRepositoryT>
 {
  /// summary>
  /// 添加
  /// /summary>
  /// param name="entity">數(shù)據(jù)實(shí)體/param>
  /// returns>添加后的數(shù)據(jù)實(shí)體/returns>
  T Add(T entity);

  /// summary>
  /// 查詢記錄數(shù)
  /// /summary>
  /// param name="predicate">條件表達(dá)式/param>
  /// returns>記錄數(shù)/returns>
  int Count(ExpressionFuncT, bool>> predicate);

  /// summary>
  /// 更新
  /// /summary>
  /// param name="entity">數(shù)據(jù)實(shí)體/param>
  /// returns>是否成功/returns>
  bool Update(T entity);

  /// summary>
  /// 刪除
  /// /summary>
  /// param name="entity">數(shù)據(jù)實(shí)體/param>
  /// returns>是否成功/returns>
  bool Delete(T entity);

  /// summary>
  /// 是否存在
  /// /summary>
  /// param name="anyLambda">查詢表達(dá)式/param>
  /// returns>布爾值/returns>
  bool Exist(ExpressionFuncT, bool>> anyLambda);

  /// summary>
  /// 查詢數(shù)據(jù)
  /// /summary>
  /// param name="whereLambda">查詢表達(dá)式/param>
  /// returns>實(shí)體/returns>
  T Find(ExpressionFuncT, bool>> whereLambda);

  /// summary>
  /// 查找數(shù)據(jù)列表
  /// /summary>
  /// typeparam name="S">排序/typeparam>
  /// param name="whereLamdba">查詢表達(dá)式/param>
  /// param name="isAsc">是否升序/param>
  /// param name="orderLamdba">排序表達(dá)式/param>
  /// returns>/returns>
  IQueryableT> FindListS>(ExpressionFuncT, bool>> whereLamdba, bool isAsc, ExpressionFuncT, S>> orderLamdba);
  
  /// summary>
  /// 查找分頁(yè)數(shù)據(jù)列表
  /// /summary>
  /// typeparam name="S">排序/typeparam>
  /// param name="pageIndex">當(dāng)前頁(yè)/param>
  /// param name="pageSize">每頁(yè)記錄數(shù)/param>
  /// param name="totalRecord">總記錄數(shù)/param>
  /// param name="whereLamdba">查詢表達(dá)式/param>
  /// param name="isAsc">是否升序/param>
  /// param name="orderLamdba">排序表達(dá)式/param>
  /// returns>/returns>
  IQueryableT> FindPageListS>(int pageIndex, int pageSize, out int totalRecord, ExpressionFuncT, bool>> whereLamdba, bool isAsc, ExpressionFuncT, S>> orderLamdba);

 }
}

這里定義了增、刪、改、判斷存在、返回模型的查詢、返回集合的查詢,返回分頁(yè)集合的查詢7個(gè)公共方法。這幾個(gè)方法基本滿足一般需要,特殊的方法在繼承的時(shí)候再添加。
還使用了泛型,在繼承的時(shí)候傳入實(shí)體類(lèi)型就可以直接繼承這些方法了。具體看下InterfaceUserRepository接口就清楚了。

using Ninesky.Models;
namespace Ninesky.IDAL
{
 /// summary>
 /// 用戶接口
 /// remarks>創(chuàng)建:2014.02.03/remarks>
 /// /summary>
 public interface InterfaceUserRepository:InterfaceBaseRepositoryUser>
 {
 }
}

簡(jiǎn)單吧,繼承自InterfaceBaseRepository接口并傳入實(shí)體類(lèi)User就行了。我們?cè)陬?lèi)視圖中看下,是不是繼承了基類(lèi)的接口。

2、DAL項(xiàng)目
DAL項(xiàng)目是對(duì)IDAL項(xiàng)目接口的實(shí)現(xiàn),項(xiàng)目中要?jiǎng)?chuàng)建DbContext類(lèi),對(duì)于DbContext類(lèi)很多人討論過(guò)它對(duì)數(shù)據(jù)庫(kù)存取的效率,MSDN中說(shuō)其是輕量的, 創(chuàng)建不需要很大開(kāi)銷(xiāo),它也不是線程安全的對(duì)象,并且具有數(shù)據(jù)容器的性質(zhì)(跟蹤),因此很多人認(rèn)為不應(yīng)該將其靜態(tài)化、單例化。但是對(duì)用戶的單次請(qǐng)求來(lái)說(shuō)實(shí)現(xiàn)DbContext唯一是合理的。 先看代碼吧,非常簡(jiǎn)單。

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

namespace Ninesky.DAL
{
 /// summary>
 /// 數(shù)據(jù)上下文
 /// remarks>創(chuàng)建:2014.02.03/remarks>
 /// /summary>
 public class NineskyDbContext:DbContext
 {
  public DbSetUser> Users { get; set; }
  public DbSetUserGroup> UserGroups { get; set; }
  public DbSetUserConfig> UserConfig { get; set; }
  public NineskyDbContext()
   : base("DefaultConnection")
  {
  }
 }
}

下面創(chuàng)建一個(gè)BaseRepository類(lèi),繼承自InterfaceBaseRepository并實(shí)現(xiàn)類(lèi)其接口的方法。

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

namespace Ninesky.DAL
{
 /// summary>
 /// 倉(cāng)儲(chǔ)基類(lèi)
 /// remarks>創(chuàng)建:2014.02.03/remarks>
 /// /summary>
 public class BaseRepositoryT>: InterfaceBaseRepositoryT> where T : class 
 {
  protected NineskyDbContext nContext = ContextFactory.GetCurrentContext();

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

  public int Count(ExpressionFuncT, bool>> predicate)
  {
   return nContext.SetT>().Count(predicate);
  }

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

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

  public bool Exist(ExpressionFuncT, bool>> anyLambda)
  {
   return nContext.SetT>().Any(anyLambda);
  }

  public T Find(ExpressionFuncT, bool>> whereLambda)
  {
   T _entity = nContext.SetT>().FirstOrDefaultT>(whereLambda);
   return _entity;
  }

  public IQueryableT> FindListS>(ExpressionFuncT, bool>> whereLamdba, bool isAsc, ExpressionFuncT, S>> orderLamdba)
  {
   var _list = nContext.SetT>().WhereT>(whereLamdba);
   if (isAsc) _list = _list.OrderByT, S>(orderLamdba);
   else _list = _list.OrderByDescendingT, S>(orderLamdba);
   return _list;
  }

  public IQueryableT> FindPageListS>(int pageIndex, int pageSize, out int totalRecord, ExpressionFuncT, bool>> whereLamdba, bool isAsc, ExpressionFuncT, S>> orderLamdba)
  {
   var _list = nContext.SetT>().WhereT>(whereLamdba);
   totalRecord = _list.Count();
   if (isAsc) _list = _list.OrderByT, S>(orderLamdba).SkipT>((pageIndex - 1) * pageSize).TakeT>(pageSize);
   else _list = _list.OrderByDescendingT, S>(orderLamdba).SkipT>((pageIndex - 1) * pageSize).TakeT>(pageSize);
   return _list;
  }
 }
}

代碼中都是對(duì)數(shù)據(jù)庫(kù)的操作。比較有看頭的是這句protected NineskyDbContext nContext = ContextFactory.GetCurrentContext();

ContextFactory是一個(gè)簡(jiǎn)單工廠類(lèi),GetCurrentContext()是一個(gè)靜態(tài)函數(shù)。利用簡(jiǎn)單工廠獲取請(qǐng)求內(nèi)的當(dāng)前DbContext,也就是請(qǐng)求內(nèi)的DbContext單例。先添加一個(gè)工廠類(lèi)ContextFactory

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

namespace Ninesky.DAL
{
 /// summary>
 /// 上下文簡(jiǎn)單工廠
 /// remarks>
 /// 創(chuàng)建:2014.02.05
 /// /remarks>
 /// /summary>
 public class ContextFactory
 {

  /// summary>
  /// 獲取當(dāng)前數(shù)據(jù)上下文
  /// /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,如果為空則初始化一個(gè)NineskyContext,如果存在則直接返回??碈allContext,MSDN中講CallContext提供對(duì)每個(gè)邏輯執(zhí)行線程都唯一的數(shù)據(jù)槽,而在WEB程序里,每一個(gè)請(qǐng)求恰巧就是一個(gè)邏輯線程所以可以使用CallContext來(lái)實(shí)現(xiàn)單個(gè)請(qǐng)求之內(nèi)的DbContext單例。

下面添加具體的倉(cāng)儲(chǔ)代碼。

在DAL中再添加一個(gè)UserRepository類(lèi),繼承自BaseRepository和InterfaceUserRepository。目的是繼承自BaseRepository類(lèi),實(shí)現(xiàn)InterfaceUserRepositor接口。

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

namespace Ninesky.DAL
{
 /// summary>
 /// 用戶倉(cāng)庫(kù)
 /// remarks>創(chuàng)建:2014.02.03/remarks>
 /// /summary>
 class UserRepository: BaseRepositoryUser>, InterfaceUserRepository
 {
 }
}

UserRepository就直接繼承了基類(lèi)中的方法,基類(lèi)中的方法能滿足絕大部分需要,UserRepository就不用再增加函數(shù)了,其他Repository類(lèi)都類(lèi)似,不在貼代碼了。

這里我們?cè)诮ㄒ粋€(gè)Repository工廠,用來(lái)返回項(xiàng)目中的所有Repository類(lèi)。

using Ninesky.IDAL;

namespace Ninesky.DAL
{
 /// summary>
 /// 簡(jiǎn)單工廠?
 /// remarks>創(chuàng)建:2014.02.03/remarks>
 /// /summary>
 public static class RepositoryFactory
 {
  /// summary>
  /// 用戶倉(cāng)儲(chǔ)
  /// /summary>
  public static InterfaceUserRepository UserRepository { get { return new UserRepository(); } }
 }
}

以后在BLL中調(diào)用的時(shí)候就不用每次都寫(xiě)InterfaceUserRepository _iUserRsy = new  UserRepository()了,直接寫(xiě)成InterfaceUserRepository _iUserRsy = RepositoryFactory.UserRepository這個(gè)東西的好處就是,以后在DAL項(xiàng)目中實(shí)現(xiàn)InterfaceUserRepository接口的類(lèi)需要修改時(shí)我們可以直接創(chuàng)建個(gè)新類(lèi),然后RepositoryFactory類(lèi)中讓UserRepository屬性返回新類(lèi)就行了。

3、IBLL項(xiàng)目
IBLL是業(yè)務(wù)邏輯層的接口,業(yè)務(wù)邏輯層對(duì)數(shù)據(jù)庫(kù)的操作上基本還是增、刪、改。同樣寫(xiě)一個(gè)基接口把這三個(gè)操作寫(xiě)進(jìn)去,這里與IDAL思路類(lèi)似。

namespace Ninesky.IBLL
{
 /// summary>
 /// 接口基類(lèi)
 /// remarks>創(chuàng)建:2014.02.03/remarks>
 /// /summary>
 public interface InterfaceBaseServiceT> where T : class
 {
  /// summary>
  /// 添加
  /// /summary>
  /// param name="entity">數(shù)據(jù)實(shí)體/param>
  /// returns>添加后的數(shù)據(jù)實(shí)體/returns>
  T Add(T entity);

  /// summary>
  /// 更新
  /// /summary>
  /// param name="entity">數(shù)據(jù)實(shí)體/param>
  /// returns>是否成功/returns>
  bool Update(T entity);

  /// summary>
  /// 刪除
  /// /summary>
  /// param name="entity">數(shù)據(jù)實(shí)體/param>
  /// returns>是否成功/returns>
  bool Delete(T entity);
 }
}


在添加一個(gè)InterfaceUserService接口,繼承自InterfaceBaseService。根據(jù)需要在接口中又添加了幾個(gè)方法。在這里對(duì)Find方法的名稱(chēng)進(jìn)行統(tǒng)一,凡是返回實(shí)體類(lèi)的名稱(chēng)為Find()或FindByXXX(),返回一組數(shù)據(jù)的方法名稱(chēng)為FindList()或FindXXXList,分頁(yè)的名稱(chēng)格式為FindPageList()或FindxxxPageList()

using Ninesky.Models;
using System.Linq;

namespace Ninesky.IBLL
{
 /// summary>
 /// 用戶相關(guān)接口
 /// remarks>
 /// 創(chuàng)建:2014.02.09
 /// /remarks>
 /// /summary>
 public interface InterfaceUserService:InterfaceBaseServiceUser>
 {

  /// 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">頁(yè)碼數(shù)/param>
  /// param name="pageSize">每頁(yè)記錄數(shù)/param>
  /// param name="totalRecord">總記錄數(shù)/param>
  /// param name="order">排序:0-ID升序(默認(rèn)),1ID降序,2注冊(cè)時(shí)間升序,3注冊(cè)時(shí)間降序,4登錄時(shí)間升序,5登錄時(shí)間降序/param>
  /// returns>/returns>
  IQueryableUser> FindPageList(int pageIndex, int pageSize, out int totalRecord,int order);
 }
}

4、BLL項(xiàng)目
BLL項(xiàng)目中要實(shí)現(xiàn)InterfaceUserService接口的方法,先添加BaseService的

using Ninesky.IBLL;
using Ninesky.IDAL;
namespace Ninesky.BLL
{
 /// summary>
 /// 服務(wù)基類(lèi)
 /// remarks>創(chuàng)建:2014.02.03/remarks>
 /// /summary>
 public abstract class BaseServiceT> : InterfaceBaseServiceT> where T : class
 {
  protected InterfaceBaseRepositoryT> CurrentRepository { get; set; }

  public BaseService(InterfaceBaseRepositoryT> 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); }
 }
}

這個(gè)類(lèi)的構(gòu)造函數(shù)中要傳入一個(gè)參數(shù)就是currentRepository 這個(gè)在繼承的時(shí)候進(jìn)行傳入。這里還是看用戶類(lèi)。

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

namespace Ninesky.BLL
{
 /// summary>
 /// 用戶服務(wù)類(lèi)
 /// remarks>
 /// 創(chuàng)建:2014.02.12
 /// /remarks>
 /// /summary>
 public class UserService:BaseServiceUser>,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 IQueryableUser> 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);
   }
   
  }
 }
}

上面這個(gè)FindPageList代碼太累贅了,一時(shí)還沒(méi)想到好方法。

5、總結(jié)
今天寫(xiě)到這里還是在想項(xiàng)目間的調(diào)用實(shí)現(xiàn),寫(xiě)了兩個(gè)base接口、兩個(gè)base類(lèi),以后其他的類(lèi)都從它們繼承,寫(xiě)法都很類(lèi)似。下次可以開(kāi)始做界面了,在Ninesky.Web項(xiàng)目中基本上是通過(guò)IBLL,BLL跟數(shù)據(jù)進(jìn)行打交道了。

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

FindPageList() 這個(gè)排序的方法確實(shí)不太通用,代碼修改如下:

1、接口 InterfaceBaseRepository

修改兩個(gè)接口方法如圖紅框部分。

image

2、BaseRepository類(lèi)

添加OrderBy方法,代碼如下:

/// summary>
  /// 排序
  /// /summary>
  /// typeparam name="T">類(lèi)型/typeparam>
  /// param name="source">原IQueryable/param>
  /// param name="propertyName">排序?qū)傩悦?param>
  /// param name="isAsc">是否正序/param>
  /// returns>排序后的IQueryableT>/returns>
  private IQueryableT> OrderBy(IQueryableT> 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.CreateQueryT>(_resultExpression);
  }
修改FindList和FindPageList方法,修改下圖

image

3、修改UserService的FindPageList方法

修改后的代碼如下:

public IQueryableUser> 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 網(wǎng)站開(kāi)發(fā)框架模型、數(shù)據(jù)存儲(chǔ)以及業(yè)務(wù)邏輯的相關(guān)介紹,比之前兩節(jié)的內(nèi)容是不是更加豐富了,希望本文可以對(duì)大家的學(xué)習(xí)有所幫助。

您可能感興趣的文章:
  • ASP.NET MVC5網(wǎng)站開(kāi)發(fā)用戶登錄、注銷(xiāo)(五)
  • PHP MVC模式在網(wǎng)站架構(gòu)中的實(shí)現(xiàn)分析
  • ASP.NET MVC5網(wǎng)站開(kāi)發(fā)用戶注冊(cè)(四)
  • MVC4 網(wǎng)站發(fā)布(整理+部分問(wèn)題收集和解決方案)
  • CodeIgniter php mvc框架 中國(guó)網(wǎng)站
  • PHP發(fā)明人談MVC和網(wǎng)站設(shè)計(jì)架構(gòu) 貌似他不支持php用mvc
  • ASP.NET MVC5網(wǎng)站開(kāi)發(fā)項(xiàng)目框架(二)
  • ASP.NET MVC5網(wǎng)站開(kāi)發(fā)顯示文章列表(九)
  • ASP.NET MVC5網(wǎng)站開(kāi)發(fā)添加文章(八)
  • 一步步打造簡(jiǎn)單的MVC電商網(wǎng)站BooksStore(1)

標(biāo)簽:汕尾 洛陽(yáng) 贛州 青海 崇左 南寧 衢州 巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《ASP.NET MVC5 網(wǎng)站開(kāi)發(fā)框架模型、數(shù)據(jù)存儲(chǔ)、業(yè)務(wù)邏輯(三)》,本文關(guān)鍵詞  ASP.NET,MVC5,網(wǎng)站開(kāi)發(fā),框架,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。

  • 相關(guān)文章
  • 下面列出與本文章《ASP.NET MVC5 網(wǎng)站開(kāi)發(fā)框架模型、數(shù)據(jù)存儲(chǔ)、業(yè)務(wù)邏輯(三)》相關(guān)的同類(lèi)信息!
  • 本頁(yè)收集關(guān)于ASP.NET MVC5 網(wǎng)站開(kāi)發(fā)框架模型、數(shù)據(jù)存儲(chǔ)、業(yè)務(wù)邏輯(三)的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    阆中市| 江城| 通榆县| 茂名市| 晋州市| 托里县| 威海市| 偏关县| 石门县| 咸阳市| 景泰县| 夏河县| 师宗县| 惠来县| 阜宁县| 连南| 宁波市| 大足县| 荃湾区| 隆尧县| 衡东县| 舞钢市| 荥经县| 米林县| 石嘴山市| 河津市| 拜泉县| 锡林郭勒盟| 浮梁县| 元氏县| 大方县| 吴桥县| 溆浦县| 同仁县| 宜黄县| 大埔县| 岢岚县| 桃源县| 昌江| 黔南| 阿图什市|