.net 網站(MVC)三層架構實踐程式碼
一.任務
建立一個.Net,C#,MVC的網站,採用三層架構,實現對一個Sql server中表資料的查詢。
二.何謂三層架構
三層架構,指的是把系統分成三個部分:資料處理層(DAL:data access layer),業務邏輯層(BLL:business logical layer),表現層(USL:user show layer)。資料處理層:負責直接對資料庫的增刪改查。業務邏輯層:呼叫資料處理層,針對具體業務,把結果轉給表現層。表現層:負責和使用者互動(輸入,輸出)。
三.何謂MVC
MVC(Model,View,Controller),模型-檢視-控制器。模型:指的是資料模型,簡單講,比如模型中可以
包含一個類person,具有name,sex,tele等屬性,當然模型內容更加可以直接用ADO.NET實體資料模型。
檢視:與使用者互動展示資料。控制器:負責尋找即將響應的檢視,並從模型層拿到資料,填充給檢視層,再
把檢視層展現出來。不同於WebForm的網站,WebForm網站中使用者直接訪問的就是各個aspx網頁,而MVC
的網站使用者直接訪問的是控制器類中的方法,每個方法去準備資料,再呈現檢視。
個人以為,可以把.Net 的WebForm方式和MVC方式看做兩種開發網站的不同方式。前者更易上手開發速度快,而後者
在系統非常龐大而複雜時更易維護但較之前者難度大。
四.步驟
1.解決方案結構和說明
各專案名簡寫~
IBLL:業務邏輯層的介面
IDAL:資料處理層的介面
BLL:業務邏輯層
Common:存放解決方案中可公用的類,如SqlHelper.cs之類
DAL:資料處理層
Model:存放資料模型
MvcApp:Web表現層
注意:各個專案之間要新增必要的相互的引用。
2.詳細結構
IBLL:類庫,業務邏輯層的介面,添加了兩個介面
IDAL:類庫,資料處理層的介面,添加了三個介面
BLL:類庫,業務邏輯層,添加了兩個類
Common:類庫,存放解決方案中可公用的類,如SqlHelper.cs之類,這裡沒有用到公用的類,什麼也沒新增
DAL:類庫,資料處理層,添加了三個類
Model:類庫,存放資料模型,添加了ADO.NET實體資料模型Model1.edmx,對應資料表MyUser
MvcApp:MVC3專案,Web表現層,添加了控制器HomeController.cs,添加了檢視Index.cshtml, Create.cshtml
3.各個新增類,介面等的說明
1)Model,在Model裡新增實體資料模型,加入Sql server中的表MyUsers。
2)IDAL,
a.新增介面 IBaseDal.cs
using CZBK.Shop.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CZBK.Shop.IDAL
{
//放公共方法
public interface IBaseDal<T>where T:class,new()//約束T的型別,是一個類,並且可以new()
{
IQueryable<T> LoadEntities(Func<T,bool>whereLambda);
T AddEntity(T item);
bool DeleteEntity(T item);
bool UpdateEntity(T item);
}
}
b.新增介面 IDBSecssion.csusing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data.Objects;
namespace CZBK.Shop.IDAL
{
public interface IDBSecssion
{
IUserInfoDal UserInfoDal { get; set; }
int ExecuteSql(string sql, params ObjectParameter[] pars);
//params 關鍵字可以指定採用數目可變的引數的方法引數
int SaveChanges();
}
}
c.新增介面 IUserInfoDal.csusing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CZBK.Shop.Model;
namespace CZBK.Shop.IDAL
{
//有專門屬於MyUsers的介面方法寫在下面
public interface IUserInfoDal:IBaseDal<MyUsers>
{
}
}
3)DAL
a.新增類 BaseDal.cs
using CZBK.Shop.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
namespace CZBK.Shop.DAL
{
public class BaseDal<T> where T:class,new()
{
//ExcrciseEntities db = new ExcrciseEntities();
ExcrciseEntities db = DbContextFactory.GetCurrentContext();
public IQueryable<T> LoadEntities(Func<T, bool> whereLambda)
{
return db.Set<T>().Where<T>(whereLambda).AsQueryable();
}
public T AddEntity(T item)
{
db.Set<T>().Add(item);
//db.SaveChanges();
return item;
}
public bool DeleteEntity(T item)
{
db.Set<T>().Remove(item);
//return db.SaveChanges() > 0;
return true;
}
public bool UpdateEntity(T item)
{
db.Entry(item).State = EntityState.Modified;
//return db.SaveChanges() > 0;
return true;
}
}
}
b.新增類 DbContextFactory.cs
using CZBK.Shop.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
namespace CZBK.Shop.DAL
{
//CallContext保證執行緒內建立的資料操作上下文是唯一的。
public class DbContextFactory
{
public static ExcrciseEntities GetCurrentContext()
{
ExcrciseEntities DbContext = (ExcrciseEntities)CallContext.GetData("context");
if (DbContext == null)
{
DbContext = new ExcrciseEntities();
CallContext.SetData("context",DbContext);
}
return DbContext;
}
}
}
c.新增類 DBSession.csusing CZBK.Shop.IDAL;
using CZBK.Shop.Model;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Objects;
using System.Data;
using System.Linq;
using System.Text;
namespace CZBK.Shop.DAL
{
/// <summary>
/// 所有的資料操作類的物件,使得業務邏輯層利用該類可拿到所有資料層的資料物件
/// </summary>
public class DBSession : IDBSecssion
{
DbContext dbContext = new ExcrciseEntities();
private IUserInfoDal _userInfoDal;
public IUserInfoDal UserInfoDal
{
get
{
if (_userInfoDal == null)
{
_userInfoDal = new UserInfoDao();
}
return _userInfoDal;
}
set
{
_userInfoDal = value;
}
}
public int ExecuteSql(string sql,params ObjectParameter[] pars)
{
return dbContext.Database.ExecuteSqlCommand(sql, pars);
}
//將業務涉及到的操作一次性的提交回資料庫
public int SaveChanges()
{
return dbContext.SaveChanges();
}
}
}
d.新增類 UserInfoDao.cs
using CZBK.Shop.IDAL;
using CZBK.Shop.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data;
namespace CZBK.Shop.DAL
{
public class UserInfoDao:BaseDal<MyUsers>,IUserInfoDal
{
}
}
4)IBLL
a.新增介面 IBaseManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CZBK.Shop.IDAL;
namespace CZBK.Shop.IBLL
{
public interface IBaseManager<T> where T:class,new()
{
IDBSecssion dbSecssion { get; }
IBaseDal<T> CurrentDal { get; set; }
IQueryable<T> LoadEntities(Func<T,bool> whereLambda);
bool AddEntity(T entity);
bool UpdateEntity(T entity);
bool DeleteEntity(T entity);
}
}
b.新增介面 IUserInfoManager.csusing CZBK.Shop.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CZBK.Shop.IBLL
{
public interface IUserInfoManager:IBaseManager<MyUsers>
{
}
}
5)BLL
a.新增類 BaseManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CZBK.Shop.DAL;
using CZBK.Shop.IDAL;
namespace CZBK.Shop.BLL
{
//業務層中公共的內容
public abstract class BaseManager<T> where T:class,new()
{
public IDBSecssion dbSecssion
{
get{ return new DBSession(); }
}
//當前要用到的資料操作類的例項
public IBaseDal<T> CurrentDal
{
get;
set;
}
public abstract void SetCurrentDal();
public BaseManager()//子類必須實現該抽象方法
{
SetCurrentDal();
}
public IQueryable<T> LoadEntities(Func<T,bool>whereLambda)
{
return CurrentDal.LoadEntities(whereLambda);
}
public bool AddEntity(T entity)
{
CurrentDal.AddEntity(entity);
return dbSecssion.SaveChanges() > 0;
}
public bool DeleteEntity(T entity)
{
CurrentDal.DeleteEntity(entity);
return dbSecssion.SaveChanges() > 0;
}
public bool UpdateEntity(T entity)
{
CurrentDal.UpdateEntity(entity);
return dbSecssion.SaveChanges() > 0;
}
}
}
b.新增類 UserInfoManager.csusing CZBK.Shop.IBLL;
using CZBK.Shop.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//BLL業務邏輯層
namespace CZBK.Shop.BLL
{
public class UserInfoManager : BaseManager<MyUsers> ,IUserInfoManager
{
public override void SetCurrentDal()
{
CurrentDal = this.dbSecssion.UserInfoDal;
}
//public void SetInfo()
//{
// dbSecssion.UserInfoDal.AddEntity(userInfo);
//}
}
}
6)Common,這個專案裡暫時沒有新增任何東西。
7)MvcApp
a.在Controllers資料夾下新增控制器HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using CZBK.Shop.IBLL;
using CZBK.Shop.IDAL;
using CZBK.Shop.BLL;
using CZBK.Shop.DAL;
using CZBK.Shop.Model;
namespace CZBK.Shop.MvcApp.Controllers
{
public class HomeController : Controller
{
IBLL.IUserInfoManager bll = new UserInfoManager();
public ActionResult Index()
{
var temp = bll.LoadEntities(u => true);
return View(temp);
}
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(MyUsers user)
{
bll.AddEntity(user);
return RedirectToAction("Index");
}
}
}
b.在上面控制器HomeController.cs的 Index方法上右擊-新增檢視-強型別-List-Razor,
專案自動在Views資料夾下生成Index.cshtml,該檔案無需更改。
c.在Create方法上右擊右擊-新增檢視-強型別-Create-Razor,
專案自動在Views資料夾下生成Create.cshtml,該檔案無需更改。
4.不斷地生成每個寫好的專案,最後執行,預設結果頁面
點選左上角Create New,進入create頁面:
5. BUG!!! 嘗試結果,Index方法和頁面執行正常。
但是在Create頁面新增一條記錄還無法儲存到資料庫。。。待改進。。。