你的位置:首页 > ASP.net教程

[ASP.net教程]从零开始,搭建博客系统MVC5+EF6搭建框架(1),EF Code frist、实现泛型数据仓储以及业务逻辑


前言

     从上篇30岁找份程序员的工作(伪程序员的独白)文章开始,我说过我要用我自学的技术,来搭建一个博客系统,也希望大家给点意见,另外我很感谢博客园的各位朋友们,对我那篇算是自我阶段总结文章的评论,在里面能看出有很多种声音,有支持的我的朋友给我加油打气,有分享自己工作经历的朋友,有提出忠肯意见的朋友,有对记事本写代码吐槽的朋友,也有希望让我换个行业的,觉得我可能不适合这个行业朋友,不管怎样,我都接受,都是大家同行的一些忠告,谢谢大家。

     首先我要在这里感谢很多博客园里面的大牛,写了很多系列,很多学习资料,让我受益很多,有机会找个时间,我会把我浏览器中收藏的资源都整理出来,分享给大家,其实我会的这些都是自己在博客园看到的文章、在某宝买的视频、QQ群里看群主的分享公开课学的,希望大家多提宝贵意见。

一、框架搭建

image

首先创建几个文件夹:

01Data用来放链接数据的EF以及创建表的类;

02Core存放数据仓储一些跟数据库链接实现数据操作的部分:

03Services 用于存放业务逻辑处理;

04Common用于放公共应用的工具之类;

05UI mvc页面展示的就放在这里 以及web相关的核心代码

 

其中除了Wchl.CRM.WebUI创建的是MVC5应用程序,其他的都是创建类库

二、创建数据库

1.创建一个空的EF code frist环境,输入的名字为WMBlogDB

image

2、选择空的Code Frist模型

image

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

image

6、修改Configuration类配置

image

7、在WMBlogDB类中重写OnModelCreating方法

image

重写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     #endregion132 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     #endregion142 143     #region 新增144     public void Add(TEntity model)145     {146       _dbSet.Add(model);147     }148     #endregion149 150     #region 统一提交151     public int SaverChanges()152     {153       return db.SaveChanges();154     }155     #endregion156 157     #region 调用存储过程返回一个指定的TResult158     public List<TResult> RunProc<TResult>(string sql, params object[] pamrs)159     {160       return db.Database.SqlQuery<TResult>(sql, pamrs).ToList();161     }162     #endregion163   }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     #endregion103 104     #region 调用存储过程返回一个指定的TResult105     public List<TResult> RunProc<TResult>(string sql, params object[] pamrs)106     {107      return baseDal.RunProc<TResult>(sql, pamrs);108     }109     #endregion110   }111 }

View Code

   到目前为止数据库、仓储层、业务逻辑层的父类和父接口都实现了,下一篇博文就在UI层怎么调用,测试看,成功写成功没。

 

谢谢大家的支持,多提宝贵意见。