[MVC學習筆記]1.項目結構搭建及單個類在各個層次中的實現

????? 新人剛開始學習ASP.NET MVC,若有不足之處希望能得到您的指點,不勝感激!

?

?????? 先來一張項目的層級結構圖:

image

????? Model:模型層,主要是各種類型、枚舉以及ORM框架,框架完成數據庫和實體類的映射。項目中選用了微軟的開源ORM框架 EntityFramework 6.0 (以下簡稱EF),數據庫則選擇了微軟的輕量級數據庫SQL Server Compact 4.0本地數據庫(簡稱Compact),Compact對EF支持比較完美,又屬于文檔型數據庫,部署起來比較簡潔。

????? DAL:數據訪問層,主要是對數據庫的操作層,為業務邏輯層或表示層提供數據服務。

????? IDAL:數據訪問接口層,是數據訪問層的接口,降低耦合。

????? DALFactory:數據會話層,封裝了所有數據操作類實例的創建,將數據訪問層與業務邏輯層解耦。

????? BLL:業務邏輯層,主要負責對數據層的操作,把一些數據層的操作進行組合以完成業務的需要。

????? IBLL:業務邏輯接口層,業務邏輯層的接口,降低耦合。

????? WebApp:表現層,是一個ASP.NET MVC項目,完成具體網站的實現。

????? Common:通用層,用來存放一些工具類。

????? 下面是各個層級之間具體的實現,首先創建以 項目名.層級名 命名的各個層次,除WebApp層為ASP.NET MVC項目外,其余均創建為類庫項目。

image

?????

?

?

模型層的構建

????? 先建立模型層,新建ASP.NET 實體數據模型,關聯到已經設計好的數據庫,EF自動完成模型類的創建。

?

image

數據訪問層的構建

????? DAL層中,我們首先需要一個方法來獲取單例的EF數據操縱上下文對象,以保證每個用戶訪問時只有使用一個上下文對象對數據庫進行操作。DbContextFactory.cs

using System.Data.Entity;
using System.Runtime.Remoting.Messaging;
using PMS.Model;namespace PMS.DAL
{public class DbContextFactory{/// <summary>/// 負責創建EF數據操作上下文實例,必須保證線程內唯一/// </summary>public static DbContext CreateContext(){DbContext dbContext = (DbContext)CallContext.GetData("dbContext");if (dbContext != null) return dbContext;dbContext = new PMSEntities();CallContext.SetData("dbContext", dbContext);return dbContext;}}
}

????? 為User類創建DAL層,實現查詢、分頁查詢、增加、刪除和修改這五個基本的方法:UserDAL.cs

using System;
using System.Data.Entity;
using System.Linq;
using PMS.IDAL;namespace PMS.DAL
{public partial class UserDal 
    {public DbContext DbEntities = DbContextFactory.CreateContext();/// <summary>/// 查詢過濾/// </summary>/// <param name="whereLamada">過濾條件Lambda表達式</param>/// <returns>實體集合</returns>public IQueryable<UserDal> LoadEntities(System.Linq.Expressions.Expression<Func<UserDal, bool>> whereLamada){return DbEntities.Set<UserDal>().Where(whereLamada);}/// <summary>/// 分頁查詢/// </summary>/// <typeparam name="TS">排序類型</typeparam>/// <param name="pageIndex">查詢的頁碼</param>/// <param name="pageSize">每頁顯示的數目</param>/// <param name="totalCount">符合條件的總行數</param>/// <param name="whereLambda">過濾條件Lambda表達式</param>/// <param name="orderbyLambda">排序Lambda表達式</param>/// <param name="isAsc">排序方向</param>/// <returns>實體集合</returns>public IQueryable<UserDal> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, System.Linq.Expressions.Expression<Func<UserDal, bool>> whereLambda, System.Linq.Expressions.Expression<Func<UserDal, TS>> orderbyLambda, bool isAsc){var temp = DbEntities.Set<UserDal>().Where(whereLambda);totalCount = temp.Count();temp = isAsc ? temp.OrderBy(orderbyLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize) : temp.OrderByDescending(orderbyLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize);return temp;}/// <summary>/// 刪除數據/// </summary>/// <param name="entity">待刪數據</param>/// <returns>刪除結果</returns>public bool DeleteEntity(UserDal entity){DbEntities.Entry(entity).State = EntityState.Deleted;return true;}/// <summary>/// 編輯數據/// </summary>/// <param name="entity">待編輯數據</param>/// <returns>編輯結果</returns>public bool EditEntity(UserDal entity){DbEntities.Entry(entity).State = EntityState.Modified;return true;}/// <summary>/// 添加數據/// </summary>/// <param name="entity">待添加數據</param>/// <returns>已添加數據</returns>public UserDal AddEntity(UserDal entity){entity = DbEntities.Set<UserDal>().Add(entity);return entity;}       }
}

注:這里的增刪改操作并不即時進行,而是在封裝在數據會話層中,以實現工作單元模式,提高數據庫的操作效率。

????? 考慮到每個類都需要實現相同的數據操作,我們可以將以上方法封裝到一個泛型基類中,各類型只需要繼承泛型基類就可以實現以上方法:BaseDal.cs

using System;
using System.Data.Entity;
using System.Linq;namespace PMS.DAL
{public class BaseDal<T> where T:class ,new(){public DbContext DbEntities = DbContextFactory.CreateContext();/// <summary>/// 查詢過濾/// </summary>/// <param name="whereLamada">過濾條件Lambda表達式</param>/// <returns>實體集合</returns>public IQueryable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T, bool>> whereLamada){return DbEntities.Set<T>().Where(whereLamada);}/// <summary>/// 分頁查詢/// </summary>/// <typeparam name="TS">排序類型</typeparam>/// <param name="pageIndex">查詢的頁碼</param>/// <param name="pageSize">每頁顯示的數目</param>/// <param name="totalCount">符合條件的總行數</param>/// <param name="whereLambda">過濾條件Lambda表達式</param>/// <param name="orderbyLambda">排序Lambda表達式</param>/// <param name="isAsc">排序方向</param>/// <returns>實體集合</returns>public IQueryable<T> LoadPageEntities<TS>(int pageIndex, int pageSize, out int totalCount, System.Linq.Expressions.Expression<Func<T, bool>> whereLambda, System.Linq.Expressions.Expression<Func<T, TS>> orderbyLambda, bool isAsc){var temp = DbEntities.Set<T>().Where(whereLambda);totalCount = temp.Count();temp = isAsc ? temp.OrderBy(orderbyLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize) : temp.OrderByDescending(orderbyLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize);return temp;}/// <summary>/// 刪除數據/// </summary>/// <param name="entity">待刪數據</param>/// <returns>刪除結果</returns>public bool DeleteEntity(T entity){DbEntities.Entry(entity).State = EntityState.Deleted;return true;}/// <summary>/// 編輯數據/// </summary>/// <param name="entity">待編輯數據</param>/// <returns>編輯結果</returns>public bool EditEntity(T entity){DbEntities.Entry(entity).State = EntityState.Modified;return true;}/// <summary>/// 添加數據/// </summary>/// <param name="entity">待添加數據</param>/// <returns>已添加數據</returns>public T AddEntity(T entity){entity = DbEntities.Set<T>().Add(entity);//DbEntities.SaveChanges();return entity;}}
}

UserDal繼承BaseDal

using PMS.IDAL;
using PMS.Model;namespace PMS.DAL
{public partial class UserDal : BaseDal<User>{}
}

數據訪問接口層的構建

????? 然后我們建立相應的IbaseDal接口和IUserDal接口,并且使UserDal類實現IUserDal接口

IBaseDal:

using System;
using System.Linq;namespace PMS.IDAL
{public interface IBaseDal<T> where T:class,new(){IQueryable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T, bool>> whereLamada);IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount,System.Linq.Expressions.Expression<Func<T, bool>> whereLambda,System.Linq.Expressions.Expression<Func<T, s>> orderbyLambda, bool isAsc);bool DeleteEntity(T entity);bool EditEntity(T entity);T AddEntity(T entity);}
}

IUserDal:

using PMS.Model;namespace PMS.IDAL
{public partial interface IUserDal:IBaseDal<User>{}
}

UserDal實現IUserDal接口:

public partial class UserDal : BaseDal<User>,IUserDal

數據會話層的構建

抽象工廠類AbstractFactory:

using System.Configuration;
using System.Reflection;
using PMS.IDAL;namespace PMS.DALFactory
{public partial class AbstractFactory{//讀取保存在配置文件中的程序集名稱與命名空間名private static readonly string AssemblyPath = ConfigurationManager.AppSettings["AssemblyPath"];private static readonly string NameSpace = ConfigurationManager.AppSettings["NameSpace"];/// <summary>/// 獲取UserDal的實例/// </summary>/// <returns></returns>public static IUserDal CreateUserInfoDal(){var fullClassName = NameSpace + ".UserInfoDal";return CreateInstance(fullClassName) as IUserDal;}/// <summary>/// 通過反射獲得程序集中某類型的實例/// </summary>/// <param name="className"></param>/// <returns></returns>private static object CreateInstance(string className){var assembly = Assembly.Load(AssemblyPath);return assembly.CreateInstance(className);}}
}

數據會話類DbSession:

using System.Data.Entity;
using PMS.IDAL;
using PMS.DAL;namespace PMS.DALFactory
{public partial class DbSession:IDbSession{public DbContext Db{get { return DbContextFactory.CreateContext(); }}private IUserDal _userDal;public IUserDal UserDal{get { return _userDal ?? (_userDal = AbstractFactory.CreateUserInfoDal()); }set { _userDal = value; }}/// <summary>/// 工作單元模式,統一保存數據/// </summary>/// <returns></returns>public bool SaveChanges(){return Db.SaveChanges() > 0;}}
}

?

?

?

業務邏輯層的構建

業務類基類BaseService

using System;
using System.Linq;
using System.Linq.Expressions;
using PMS.DALFactory;
using PMS.IDAL;namespace PMS.BLL
{public abstract class BaseService<T> where T:class,new(){public IDbSession CurrentDbSession{get{return new DbSession();}}public IBaseDal<T> CurrentDal { get; set; }public abstract void SetCurrentDal();public BaseService(){SetCurrentDal();//子類一定要實現抽象方法,以指明當前類的子類類型。
       }/// <summary>/// 查詢過濾/// </summary>/// <param name="whereLambda"></param>/// <returns></returns>public IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda){return CurrentDal.LoadEntities(whereLambda);}/// <summary>/// 分頁/// </summary>/// <typeparam name="s"></typeparam>/// <param name="pageIndex"></param>/// <param name="pageSize"></param>/// <param name="totalCount"></param>/// <param name="whereLambda"></param>/// <param name="orderbyLambda"></param>/// <param name="isAsc"></param>/// <returns></returns>public IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, Expression<Func<T, bool>> whereLambda,Expression<Func<T, s>> orderbyLambda, bool isAsc){return CurrentDal.LoadPageEntities<s>(pageIndex, pageSize, out totalCount, whereLambda, orderbyLambda, isAsc);}/// <summary>/// 刪除/// </summary>/// <param name="entity"></param>/// <returns></returns>public bool DeleteEntity(T entity){CurrentDal.DeleteEntity(entity);return CurrentDbSession.SaveChanges();}/// <summary>/// 編輯/// </summary>/// <param name="entity"></param>/// <returns></returns>public bool EditEntity(T entity){CurrentDal.EditEntity(entity);return CurrentDbSession.SaveChanges();}/// <summary>/// 添加數據/// </summary>/// <param name="entity"></param>/// <returns></returns>public T AddEntity(T entity){CurrentDal.AddEntity(entity);CurrentDbSession.SaveChanges();return entity;}}
}

?

UserService類:

using PMS.IBLL;
using PMS.Model;namespace PMS.BLL
{public partial class UserService : BaseService<User>{public override void SetCurrentDal(){CurrentDal = CurrentDbSession.UserDal;}}
}

?

?

?

業務邏輯接口層的構建

????? 直接建立對應的接口并使用UserService類實現IUserService接口

IBaseService接口:

using System;
using System.Linq;
using System.Linq.Expressions;
using PMS.IDAL;namespace PMS.IBLL
{public interface IBaseService<T> where T : class,new(){IDbSession CurrentDbSession { get; }IBaseDal<T> CurrentDal { get; set; }void SetCurrentDal();IQueryable<T> LoadEntities(Expression<Func<T, bool>> whereLambda);IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount,Expression<Func<T, bool>> whereLambda,Expression<Func<T, s>> orderbyLambda, bool isAsc);bool DeleteEntity(T entity);bool EditEntity(T entity);T AddEntity(T entity);}
}

IUserService接口:

using PMS.Model;namespace PMS.IBLL
{public partial interface IUserService:IBaseService<User>{}
}

使用UserService類實現IUserService接口:

public partial class UserService : BaseService<User>, IUserService

?

?

以上我們就完成了整個框架中關于User類的各層次的實現。

轉載于:https://www.cnblogs.com/WayneShao/p/5876880.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/542568.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/542568.shtml
英文地址,請注明出處:http://en.pswp.cn/news/542568.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

日期getUTCSeconds()方法以及JavaScript中的示例

JavaScript日期getUTCSeconds()方法 (JavaScript Date getUTCSeconds() method) getUTCSeconds() method is a Dates class method and it is used to get seconds from the current time according to the UTC (Universal time coordinated). getUTCSeconds()方法是Date的類方…

dedecms 在模板里引入php文件夾,dedecms如何添加并引入php文件

前言&#xff1a;有些時候我們需要創建一些單獨的PHP文件&#xff0c;但是隨便放入的PHP文件是不能夠編譯織夢 dedecms的標簽的&#xff0c;所以我們需要引入織夢標簽的編譯引擎方案。例如&#xff0c;我們在根目錄創建 example.php&#xff0c;代碼如下&#xff1a;<?php …

mybatisplus代碼生成器_想做時間管理大師?你可以試試Mybatis Plus代碼生成器

1. 前言對于寫Crud的老司機來說時間非常寶貴&#xff0c;一些樣板代碼寫不但費時費力&#xff0c;而且枯燥無味。經常有小伙伴問我&#xff0c;胖哥你怎么天天那么有時間去搞新東西&#xff0c;透露一下秘訣唄。好吧&#xff0c;今天就把Mybatis-plus的代碼生成器分享出來&…

安裝Oracle 11g RAC R2 之Linux DNS 配置

Oracle 11g RAC 集群中引入了SCAN(Single Client Access Name)的概念&#xff0c;也就是指集群的單客戶端訪問名稱。SCAN 這個特性為客戶端提供了單一的主機名&#xff0c;用于訪問集群中運行的 Oracle 數據庫。如果您在集群中添加或刪除節點&#xff0c;使用 SCAN 的客戶端無需…

c++ websocket客戶端_websocket使用

websocket使用一、介紹在項目開發過程中&#xff0c;很多時候&#xff0c;我們不可避免的需要實現的一個功能&#xff1a; 服務端實時發送信息給客戶端。比如實時公告、實時訂單通知、實時報警推送等等&#xff0c;登錄后的客戶端需要知道與它相關的實時信息&#xff0c;以便進…

漢子編碼比字母編碼長_字母/博客作者編碼問題(使用動態編程)

漢子編碼比字母編碼長Problem statement: 問題陳述&#xff1a; Shivang is a blog writer and he is working on two websites simultaneously. He has to write two types of blogs which are: Shivang是一位博客作家&#xff0c;他同時在兩個網站上工作。 他必須寫兩種類型…

php parent報錯,mac brew 安裝php擴展報錯:parent directory is world writable but not sticky

$ brew install php70-mcrypt報錯&#xff1a;Error: parent directory is world writable but not sticky搜索到github的答案https://github.com/Homebrew/legacy-homebrew/issues/40345原因&#xff1a;/tmp目錄權限不對$ ls -ld /private/tmp打印出來 /private/tmp 被標黃了…

在cordova中使用HTML5的多文件上傳

2019獨角獸企業重金招聘Python工程師標準>>> 我們先看看linkface給開放的接口&#xff1a; 字段類型必需描述api_idstring是API 賬戶api_secretstring是API 密鑰selfie_filefile見下方注釋需上傳的圖片文件 1&#xff0c;上傳本地圖片進行檢測時選取此參數selfie_ur…

python dataframe切片_python pandas dataframe 行列選擇,切片操作方法

SQL中的select是根據列的名稱來選取&#xff1b;Pandas則更為靈活&#xff0c;不但可根據列名稱選取&#xff0c;還可以根據列所在的position&#xff08;數字&#xff0c;在第幾行第幾列&#xff0c;注意pandas行列的position是從0開始&#xff09;選取。相關函數如下&#xf…

php根據設備判斷訪問,PHP判斷設備訪問來源

/*** 判斷用戶請求設備是否是移動設備* return bool*/function isMobile() {//如果有HTTP_X_WAP_PROFILE則一定是移動設備if (isset($_SERVER[HTTP_X_WAP_PROFILE])) {return true;}//如果via信息含有wap則一定是移動設備,部分服務商會屏蔽該信息if (isset($_SERVER[HTTP_VIA])…

機器學習 深度學習 ai_如何學習機器學習和人工智能?

機器學習 深度學習 aiSTRATEGY 戰略 Learn theory practical aspects. 學習理論和實踐方面的知識。 (At first get an overview of what you are going to learn). (首先獲得要學習的內容的概述)。 Gain a good hold/insight on each concept. 掌握/理解每個概念。 If you …

linux常用命令和配置

2019獨角獸企業重金招聘Python工程師標準>>> 啟動php&#xff1a; /etc/init.d/php-fpm restart 查看PHP運行目錄&#xff1a; which php /usr/bin/php 查看php-fpm進程數&#xff1a; ps aux | grep -c php-fpm 查看運行內存 /usr/bin/php -i|grep mem iptables如…

centos7時間同步_centos 8.x系統配置chrony時間同步服務

centos 8.x系統配置chrony時間同步服務CentOS 7.x默認使用的時間同步服務為ntp服務&#xff0c;但是CentOS 8開始在官方的倉庫中移除了ntp軟件&#xff0c;換成默認的chrony進行時間同步的服務&#xff0c;chrony既可以作為客戶端向其他時間服務器發送時間同步請求&#xff0c;…

php可以用scanf,C/C++中 使用scanf和printf如何讀入輸出double型數據。

黃舟2017-04-17 13:47:232樓注意scanf函數和printf函數是不同尋常的函數&#xff0c;因為它們都沒有將函數的參數限制為固定數量。scanf函數和printf函數又可變長度的參數列表。當調用帶可變長度參數列表的函數時&#xff0c;編譯器會安排float參數自動轉換成為double類型&…

ICWAI和ICWA的完整形式是什么?

ICWAI / ICWA&#xff1a;印度成本與工程會計師協會/印度兒童福利法 (ICWAI / ICWA: Institute of Cost and Works Accountants of India / Indian Child Welfare Act) 1)ICWAI&#xff1a;印度成本與工程會計師協會 (1) ICWAI: Institute of Cost and Works Accountants of In…

深入研究java.lang.Runtime類【轉】

轉自&#xff1a;http://blog.csdn.net/lastsweetop/article/details/3961911 目錄(?)[-] javalang 類 RuntimegetRuntimeexitaddShutdownHookremoveShutdownHookhaltrunFinalizersOnExitexecexecexecexecexecexecavailableProcessorsfreeMemorytotalMemorymaxMemorygcrunFina…

java隊列實現限流,java中應對高并發的兩種策略

目的&#xff1a;提高可用性通過ExecutorService實現隊列泄洪//含有20個線程的線程池private ExecutorService executorService Executors.newFixedThreadPool(20);將有并發壓力的下游代碼放入到線程池的submit方法中&#xff0c;如下&#xff1a;//同步調用線程池的submit方法…

crontab 日志_liunx 中定時清理過期日志文件

問題描述經常遇到日志文件過多&#xff0c;占用大量磁盤空間&#xff0c;需要定期刪除過期日志。問題涉及方面刪除過期日志的腳本。定時任務刪除任務腳本先查詢到過期的日志文件&#xff0c;然后刪除。語法find path -option [ -print ] [ -exec -ok command ] …

JavaScript | 數組的常用屬性和方法

JavaScript的通用屬性和數組方法 (Common properties and methods of array in JavaScript ) Properties/MethodsDescriptionsarray.lengthReturns the length of the array/total number of elements of the array array[index]Returns the item name stored at “index” pos…

php dbutils 使用,dbutilsapi

相對lisp?而?言,可以使?用.net的強?大api,實現各種酷炫功能。相對c#及arx?...文件utils.py的模塊名分別是mycompany.utils和 mycompany.web.utils。 mycompany......CouchDB -b 關閉后臺運行的 CouchDB : CouchDB -d web 訪問:http://127.0.0.1:5984/_utils/index.html E-…