前言
從上篇30歲找份程式員的工作(僞程式員的獨白),文章開始,我說過我要用我自學的技術,來搭建一個部落格系統,也希望大家給點意見,另外我很感謝部落格園的各位朋友們,對我那篇算是自我階段總結文章的評論,在裡面能看出有很多種聲音,有支援的我的朋友給我加油打氣,有分享自己工作經曆的朋友,有提出忠肯意見的朋友,有對記事本寫代碼吐槽的朋友,也有希望讓我換個行業的,覺得我可能不适合這個行業朋友,不管怎樣,我都接受,都是大家同行的一些忠告,謝謝大家。
首先我要在這裡感謝很多部落格園裡面的大牛,寫了很多系列,很多學習資料,讓我受益很多,有機會找個時間,我會把我浏覽器中收藏的資源都整理出來,分享給大家,其實我會的這些都是自己在部落格園看到的文章、在某寶買的視訊、QQ群裡看群主的分享公開課學的,希望大家多提寶貴意見。
一、架構搭建
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iN4gTO1AzM1gTMtQzM5UjM0QDOxIjM5AjNxAjMtgTOxYTO18CX5AjNxAjMvwFO5EjN5UzLcd2bsJ2Lc12bj5ycn9Gbi52YuUTMwIzcldWYtl2Lc9CX6MHc0RHaiojIsJye.png)
首先建立幾個檔案夾:
01Data用來放連結資料的EF以及建立表的類;
02Core存放資料倉儲一些跟資料庫連結實作資料操作的部分:
03Services 用于存放業務邏輯處理;
04Common用于放公共應用的工具之類;
05UI mvc頁面展示的就放在這裡 以及web相關的核心代碼
其中除了Wchl.CRM.WebUI建立的是MVC5應用程式,其他的都是建立類庫
二、建立資料庫
1.建立一個空的EF code frist環境,輸入的名字為WMBlogDB
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 }
關于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 }
二、倉儲層建設
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 }
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 }
三、業務邏輯層父接口和父類建立
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 }
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 }
到目前為止資料庫、倉儲層、業務邏輯層的父類和父接口都實作了,下一篇博文就在UI層怎麼調用,測試看,成功寫成功沒。
謝謝大家的支援,多提寶貴意見。