前言 從上篇30歲找份程式員的工作(偽程式員的獨白),文章開始,我說過我要用我自學的技術,來搭建一個博客系統,也希望大家給點意見,另外我很感謝博客園的各位朋友們,對我那篇算是自我階段總結文章的評論,在裡面能看出有很多種聲音,有支持的我的朋友給我加油打氣,有分享自己工作經歷的朋友,有提出忠肯意見的朋友 ...
前言
從上篇30歲找份程式員的工作(偽程式員的獨白),文章開始,我說過我要用我自學的技術,來搭建一個博客系統,也希望大家給點意見,另外我很感謝博客園的各位朋友們,對我那篇算是自我階段總結文章的評論,在裡面能看出有很多種聲音,有支持的我的朋友給我加油打氣,有分享自己工作經歷的朋友,有提出忠肯意見的朋友,有對記事本寫代碼吐槽的朋友,也有希望讓我換個行業的,覺得我可能不適合這個行業朋友,不管怎樣,我都接受,都是大家同行的一些忠告,謝謝大家。
首先我要在這裡感謝很多博客園裡面的大牛,寫了很多系列,很多學習資料,讓我受益很多,有機會找個時間,我會把我瀏覽器中收藏的資源都整理出來,分享給大家,其實我會的這些都是自己在博客園看到的文章、在某寶買的視頻、QQ群里看群主的分享公開課學的,希望大家多提寶貴意見。
一、框架搭建
首先創建幾個文件夾:
01Data用來放鏈接數據的EF以及創建表的類;
02Core存放數據倉儲一些跟資料庫鏈接實現數據操作的部分:
03Services 用於存放業務邏輯處理;
04Common用於放公共應用的工具之類;
05UI mvc頁面展示的就放在這裡 以及web相關的核心代碼
其中除了Wchl.CRM.WebUI創建的是MVC5應用程式,其他的都是創建類庫
二、創建資料庫
1.創建一個空的EF code frist環境,輸入的名字為WMBlogDB
2、選擇空的Code Frist模型
3、創建一個models文件存放所有表的類,這裡先創建一個用戶信息表的類sysUserInfo
sysUserInfo類:
1 namespace Wchl.WMBlog.Model.Models 2 { 3 public class sysUserInfo 4 { 5 /// <summary> 6 /// 用戶ID 7 /// </summary> 8 public int uID { get; set; } 9 /// <summary> 10 /// 登錄賬號 11 /// </summary> 12 public string uLoginName { get; set; } 13 /// <summary> 14 /// 登錄密碼 15 /// </summary> 16 public string uLoginPWD { get; set; } 17 /// <summary> 18 /// 真實姓名 19 /// </summary> 20 public string uRealName { get; set; } 21 /// <summary> 22 /// 狀態 23 /// </summary> 24 public int uStatus { get; set; } 25 /// <summary> 26 /// 備註 27 /// </summary> 28 public string uRemark { get; set; } 29 /// <summary> 30 /// 創建時間 31 /// </summary> 32 public System.DateTime uCreateTime { get; set; } 33 /// <summary> 34 /// 更新時間 35 /// </summary> 36 public System.DateTime uUpdateTime { get; set; } 37 } 38 }View Code
4、創建一個maps文件夾,主要是用來放對錶欄位進行約束的類sysUserInfoMap
sysUserInfoMap類:
1 namespace Wchl.WMBlog.Model.Maps 2 { 3 public class sysUserInfoMap:EntityTypeConfiguration<sysUserInfo> 4 { 5 public sysUserInfoMap() 6 { 7 this.HasKey(u => u.uID); 8 this.Property(u => u.uLoginName).HasMaxLength(60); 9 this.Property(u => u.uLoginPWD).HasMaxLength(60); 10 this.Property(u => u.uRealName).HasMaxLength(60); 11 } 12 } 13 }View Code
關於EntityTypeConfiguration類的用法,大家可以去看看博客園裡面一些介紹文章,HasKey設置主鍵,HasMaxLength欄位最大長度。
5、在控制臺中創建資料庫腳本 Enable-Migrations
6、修改Configuration類配置
7、在WMBlogDB類中重寫OnModelCreating方法
重寫OnModelCreating方法:
1 protected override void OnModelCreating(DbModelBuilder modelBuilder) 2 { 3 //移除表名為複數 4 modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 5 //自動添加實現EntityTypeConfiguration的類 6 modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly()); 7 base.OnModelCreating(modelBuilder); 8 }View Code
二、倉儲層建設
1、在Wchl.WMBlog.IRepository中創建一個類,做為操作數據的父介面IBaseRepository,這裡使用泛型來創建
IBaseRepository介面
1 namespace Wchl.WMBlog.IRepository.Base 2 { 3 public interface IBaseRepository<TEntity> where TEntity:class 4 { 5 #region 查詢 6 /// <summary> 7 /// 單表查詢 8 /// </summary> 9 /// <param name="predicate"></param> 10 /// <returns></returns> 11 List<TEntity> QueryWhere(Expression<Func<TEntity, bool>> predicate); 12 13 /// <summary> 14 /// 多表關聯查詢 15 /// </summary> 16 /// <param name="predicate"></param> 17 /// <param name="tableNames"></param> 18 /// <returns></returns> 19 List<TEntity> QueryJoin(Expression<Func<TEntity, bool>> predicate, string[] tableNames); 20 /// <summary> 21 /// 升序查詢還是降序查詢 22 /// </summary> 23 /// <typeparam name="TKey"></typeparam> 24 /// <param name="predicate"></param> 25 /// <param name="keySelector"></param> 26 /// <param name="IsQueryOrderBy"></param> 27 /// <returns></returns> 28 List<TEntity> QueryOrderBy<TKey>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy); 29 30 /// <summary> 31 /// 升序分頁查詢還是降序分頁 32 /// </summary> 33 /// <typeparam name="TKey"></typeparam> 34 /// <param name="pageIndex">第幾頁</param> 35 /// <param name="pagesize">一頁多少條</param> 36 /// <param name="rowcount">返回共多少條</param> 37 /// <param name="predicate">查詢條件</param> 38 /// <param name="keySelector">排序欄位</param> 39 /// <param name="IsQueryOrderBy">true為升序 false為降序</param> 40 /// <returns></returns> 41 List<TEntity> QueryByPage<TKey>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy); 42 #endregion 43 44 #region 編輯 45 /// <summary> 46 /// 通過傳入的model加需要修改的欄位來更改數據 47 /// </summary> 48 /// <param name="model"></param> 49 /// <param name="propertys"></param> 50 void Edit(TEntity model, string[] propertys); 51 52 /// <summary> 53 /// 直接查詢之後再修改 54 /// </summary> 55 /// <param name="model"></param> 56 void Edit(TEntity model); 57 #endregion 58 59 #region 刪除 60 void Delete(TEntity model, bool isadded); 61 #endregion 62 63 #region 新增 64 void Add(TEntity model); 65 #endregion 66 67 #region 統一提交 68 int SaverChanges(); 69 #endregion 70 71 #region 調用存儲過程返回一個指定的TResult 72 List<TResult> RunProc<TResult>(string sql, params object[] pamrs); 73 #endregion 74 } 75 }View Code
2、然後實現IBaseRepository介面,在Wchl.WMBlog.Repository程式集中創建BaseRepository類來實現對數據操作的查詢、增加、刪除、編輯等。
BaseRepository類
1 namespace Wchl.WMBlog.Repository.Base 2 { 3 public class BaseRepository<TEntity>: IBaseRepository<TEntity> where TEntity:class 4 { 5 WMBlogDB db = new WMBlogDB(); 6 7 DbSet<TEntity> _dbSet; 8 9 public BaseRepository() 10 { 11 _dbSet = db.Set<TEntity>(); 12 } 13 14 #region 查詢 15 /// <summary> 16 /// 單表查詢 17 /// </summary> 18 /// <param name="predicate"></param> 19 /// <returns></returns> 20 public List<TEntity> QueryWhere(Expression<Func<TEntity, bool>> predicate) 21 { 22 return _dbSet.Where(predicate).ToList(); 23 } 24 25 /// <summary> 26 /// 多表關聯查詢 27 /// </summary> 28 /// <param name="predicate"></param> 29 /// <param name="tableNames"></param> 30 /// <returns></returns> 31 public List<TEntity> QueryJoin(Expression<Func<TEntity, bool>> predicate, string[] tableNames) 32 { 33 if (tableNames == null && tableNames.Any() == false) 34 { 35 throw new Exception("缺少連表名稱"); 36 } 37 38 DbQuery<TEntity> query = _dbSet; 39 40 foreach (var table in tableNames) 41 { 42 query = query.Include(table); 43 } 44 45 return query.Where(predicate).ToList(); 46 } 47 48 /// <summary> 49 /// 升序查詢還是降序查詢 50 /// </summary> 51 /// <typeparam name="TKey"></typeparam> 52 /// <param name="predicate"></param> 53 /// <param name="keySelector"></param> 54 /// <param name="IsQueryOrderBy"></param> 55 /// <returns></returns> 56 public List<TEntity> QueryOrderBy<TKey>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector,bool IsQueryOrderBy) 57 { 58 if (IsQueryOrderBy) 59 { 60 return _dbSet.Where(predicate).OrderBy(keySelector).ToList(); 61 } 62 return _dbSet.Where(predicate).OrderByDescending(keySelector).ToList(); 63 64 } 65 66 /// <summary> 67 /// 升序分頁查詢還是降序分頁 68 /// </summary> 69 /// <typeparam name="TKey"></typeparam> 70 /// <param name="pageIndex">第幾頁</param> 71 /// <param name="pagesize">一頁多少條</param> 72 /// <param name="rowcount">返回共多少條</param> 73 /// <param name="predicate">查詢條件</param> 74 /// <param name="keySelector">排序欄位</param> 75 /// <param name="IsQueryOrderBy">true為升序 false為降序</param> 76 /// <returns></returns> 77 public List<TEntity> QueryByPage<TKey>(int pageIndex,int pagesize,out int rowcount,Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy) 78 { 79 rowcount = _dbSet.Count(predicate); 80 if (IsQueryOrderBy) 81 { 82 return _dbSet.Where(predicate).OrderBy(keySelector).Skip((pageIndex - 1) * pagesize).Take(pagesize).ToList(); 83 } 84 else 85 { 86 return _dbSet.Where(predicate).OrderByDescending(keySelector).Skip((pageIndex - 1) * pagesize).Take(pagesize).ToList(); 87 } 88 } 89 #endregion 90 91 #region 編輯 92 /// <summary> 93 /// 通過傳入的model加需要修改的欄位來更改數據 94 /// </summary> 95 /// <param name="model"></param> 96 /// <param name="propertys"></param> 97 public void Edit(TEntity model, string[] propertys) 98 { 99 if (model == null) 100 { 101 throw new Exception("實體不能為空"); 102 } 103 104 if (propertys.Any() == false) 105 { 106 throw new Exception("要修改的屬性至少要有一個"); 107 } 108 109 //將model追擊到EF容器 110 DbEntityEntry entry = db.Entry(model); 111 112 entry.State = EntityState.Unchanged; 113 114 foreach (var item in propertys) 115 { 116 entry.Property(item).IsModified = true; 117 } 118 119 //關閉EF對於實體的合法性驗證參數 120 db.Configuration.ValidateOnSaveEnabled = false; 121 } 122 123 /// <summary> 124 /// 直接查詢之後再修改 125 /// </summary> 126 /// <param name="model"></param> 127 public void Edit(TEntity model) 128 { 129 db.Entry(model).State = EntityState.Modified; 130 } 131 #endregion 132 133 #region 刪除 134 public void Delete(TEntity model, bool isadded) 135 { 136 if (!isadded) { 137 _dbSet.Attach(model); 138 } 139 _dbSet.Remove(model); 140 } 141 #endregion 142 143 #region 新增 144 public void Add(TEntity model) 145 { 146 _dbSet.Add(model); 147 } 148 #endregion 149 150 #region 統一提交 151 public int SaverChanges() 152 { 153 return db.SaveChanges(); 154 } 155 #endregion 156 157 #region 調用存儲過程返回一個指定的TResult 158 public List<TResult> RunProc<TResult>(string sql, params object[] pamrs) 159 { 160 return db.Database.SqlQuery<TResult>(sql, pamrs).ToList(); 161 } 162 #endregion 163 } 164 }View Code
三、業務邏輯層父介面和父類創建
1、在Wchl.WMBlog.IServices程式集中創建IBaseServices介面
IBaseServices介面:
1 namespace Wchl.WMBlog.IServices.Base 2 { 3 public interface IBaseServices<TEntity> where TEntity:class 4 { 5 #region 查詢 6 /// <summary> 7 /// 單表查詢 8 /// </summary> 9 /// <param name="predicate"></param> 10 /// <returns></returns> 11 List<TEntity> QueryWhere(Expression<Func<TEntity, bool>> predicate); 12 13 /// <summary> 14 /// 多表關聯查詢 15 /// </summary> 16 /// <param name="predicate"></param> 17 /// <param name="tableNames"></param> 18 /// <returns></returns> 19 List<TEntity> QueryJoin(Expression<Func<TEntity, bool>> predicate, string[] tableNames); 20 /// <summary> 21 /// 升序查詢還是降序查詢 22 /// </summary> 23 /// <typeparam name="TKey"></typeparam> 24 /// <param name="predicate"></param> 25 /// <param name="keySelector"></param> 26 /// <param name="IsQueryOrderBy"></param> 27 /// <returns></returns> 28 List<TEntity> QueryOrderBy<TKey>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy); 29 30 /// <summary> 31 /// 升序分頁查詢還是降序分頁 32 /// </summary> 33 /// <typeparam name="TKey"></typeparam> 34 /// <param name="pageIndex">第幾頁</param> 35 /// <param name="pagesize">一頁多少條</param> 36 /// <param name="rowcount">返回共多少條</param> 37 /// <param name="predicate">查詢條件</param> 38 /// <param name="keySelector">排序欄位</param> 39 /// <param name="IsQueryOrderBy">true為升序 false為降序</param> 40 /// <returns></returns> 41 List<TEntity> QueryByPage<TKey>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy); 42 #endregion 43 44 #region 編輯 45 /// <summary> 46 /// 通過傳入的model加需要修改的欄位來更改數據 47 /// </summary> 48 /// <param name="model"></param> 49 /// <param name="propertys"></param> 50 void Edit(TEntity model, string[] propertys); 51 52 /// <summary> 53 /// 直接查詢之後再修改 54 /// </summary> 55 /// <param name="model"></param> 56 void Edit(TEntity model); 57 #endregion 58 59 #region 刪除 60 void Delete(TEntity model, bool isadded); 61 #endregion 62 63 #region 新增 64 void Add(TEntity model); 65 #endregion 66 67 #region 統一提交 68 int SaverChanges(); 69 #endregion 70 71 #region 調用存儲過程返回一個指定的TResult 72 List<TResult> RunProc<TResult>(string sql, params object[] pamrs); 73 #endregion 74 } 75 }View Code
2、在Wchl.WMBlog.Services程式集創建BaseServices類
BaseServices類
1 namespace Wchl.WMBlog.Services.Base 2 { 3 public class BaseServices<TEntity>: IBaseServices<TEntity> where TEntity:class 4 { 5 public IBaseRepository<TEntity> baseDal = new BaseRepository<TEntity>(); 6 7 #region 查詢 8 /// <summary> 9 /// 單表查詢 10 /// </summary> 11 /// <param name="predicate"></param> 12 /// <returns></returns> 13 public List<TEntity> QueryWhere(Expression<Func<TEntity, bool>> predicate) 14 { 15 return baseDal.QueryWhere(predicate); 16 } 17 18 /// <summary> 19 /// 多表關聯查詢 20 /// </summary> 21 /// <param name="predicate"></param> 22 /// <param name="tableNames"></param> 23 /// <returns></returns> 24 public List<TEntity> QueryJoin(Expression<Func<TEntity, bool>> predicate, string[] tableNames) 25 { 26 return baseDal.QueryJoin(predicate, tableNames); 27 28 } 29 30 /// <summary> 31 /// 升序查詢還是降序查詢 32 /// </summary> 33 /// <typeparam name="TKey"></typeparam> 34 /// <param name="predicate"></param> 35 /// <param name="keySelector"></param> 36 /// <param name="IsQueryOrderBy"></param> 37 /// <returns></returns> 38 public List<TEntity> QueryOrderBy<TKey>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy) 39 { 40 return baseDal.QueryOrderBy(predicate, keySelector, IsQueryOrderBy); 41 } 42 43 /// <summary> 44 /// 升序分頁查詢還是降序分頁 45 /// </summary> 46 /// <typeparam name="TKey"></typeparam> 47 /// <param name="pageIndex">第幾頁</param> 48 /// <param name="pagesize">一頁多少條</param> 49 /// <param name="rowcount">返回共多少條</param> 50 /// <param name="predicate">查詢條件</param> 51 /// <param name="keySelector">排序欄位</param> 52 /// <param name="IsQueryOrderBy">true為升序 false為降序</param> 53 /// <returns></returns> 54 public List<TEntity> QueryByPage<TKey>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy) 55 { 56 57 return baseDal.QueryByPage(pageIndex, pagesize,out rowcount, predicate, keySelector, IsQueryOrderBy); 58 59 } 60 #endregion 61 62 #region 編輯 63 /// <summary> 64 /// 通過傳入的model加需要修改的欄位來更改數據 65 /// </summary> 66 /// <param name="model"></param> 67 /// <param name="propertys"></param> 68 public void Edit(TEntity model, string[] propertys) 69 { 70 baseDal.Edit(model, propertys); 71 } 72 73 /// <summary> 74 /// 直接查詢之後再修改 75 /// </summary> 76 /// <param name="model"></param> 77 public void Edit(TEntity model) 78 { 79 baseDal.Edit(model); 80 } 81 #endregion 82 83 #region 刪除 84 public void Delete(TEntity model, bool isadded) 85 { 86 baseDal.Delete(model, isadded); 87 } 88 #endregion 89 90 #region 新增 91 public void Add(TEntity model) 92 { 93 baseDal.Add(model); 94 } 95 #endregion 96 97 #region 統一提交 98 public int SaverChanges() 99 { 100 return baseDal.SaverChanges(); 101 } 102 #endregion 103 104 #region 調用存儲過程返回一個指定的TResult 105 public List<TResult> RunProc<TResult>(string sql, params object[] pamrs) 106 { 107 return baseDal.RunProc<TResult>(sql, pamrs); 108 } 109 #endregion 110 } 111 }View Code
到目前為止資料庫、倉儲層、業務邏輯層的父類和父介面都實現了,下一篇博文就在UI層怎麼調用,測試看,成功寫成功沒。
謝謝大家的支持,多提寶貴意見。