【干货】利用MVC5+EF6搭建博客系统(一)EF Code frist、实现泛型数据仓储以及业务逻辑
习MVC有一段时间了,决定自己写一套Demo了,写完源码再共享。
PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可。
一、框架搭建
二、创建数据库
1.创建一个空的EF code frist环境,输入的名字为52MVCBlogDB
2、选择空的Code Frist模型
3、创建一个Models文件存放所有表的类,这里先创建一个用户信息表的类sysUserInfo
sysUserInfo类:
class sysUserInfo { /// <summary> /// 用户ID /// </summary> public int uID { get; set; } /// <summary> /// 登录账号 /// </summary> public string uLoginName { get; set; } /// <summary> /// 登录密码 /// </summary> public string uLoginPWD { get; set; } /// <summary> /// 真实姓名 /// </summary> public string uRealName { get; set; } /// <summary> /// 状态 /// </summary> public int uStatus { get; set; } /// <summary> /// 备注 /// </summary> public string uRemark { get; set; } /// <summary> /// 创建时间 /// </summary> public System.DateTime uCreateTime { get; set; } /// <summary> /// 更新时间 /// </summary> public System.DateTime uUpdateTime { get; set; } }
4、创建一个Maps文件夹,主要是用来放对表字段进行约束的类sysUserInfoMap
sysUserInfoMap类:
namespace _52MVCBlog.Model.Maps { public class sysUserInfoMap : System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<sysUserInfo> { public sysUserInfoMap() { this.HasKey(u => u.uID); this.Property(u => u.uLoginName).HasMaxLength(60); this.Property(u => u.uLoginPWD).HasMaxLength(60); this.Property(u => u.uRealName).HasMaxLength(60); } } }
5、在控制台中创建数据库脚本 Enable-Migrations(这里没有修改App.config里面的数据库连接串,使用的是默认的数据库)
6、修改Configuration类配置
7、在_52MVCBlogDB类中重写OnModelCreating方法
protected override void OnModelCreating(DbModelBuilder modelBuilder) { //移除表名为复数 modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>(); //此方法可以将当前程序集下所有继承了ComplexTypeConfiguration、EntityTypeConfiguration类型的类添加到注册器 //自动添加实现EntityTypeConfiguration的类(不再需要public virtual DbSet<MyEntity> MyEntities { get; set; }) modelBuilder.Configurations.AddFromAssembly(System.Reflection.Assembly.GetExecutingAssembly()); base.OnModelCreating(modelBuilder); }
二、仓储层建设
1、在52MVCBlog.IRepository中创建一个类,做为操作数据的父接口IBaseRepository,这里使用泛型来创建
IBaseRepository接口代码:
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace _52MVCBlog.IRepository.Base { public interface IBaseRepository<TEntity> where TEntity : class { #region 查询 /// <summary> /// 单表查询 /// </summary> /// <param name="predicate"></param> /// <returns></returns> List<TEntity> QueryWhere(Expression<Func<TEntity, bool>> predicate); /// <summary> /// 多表关联查询 /// </summary> /// <param name="predicate"></param> /// <param name="tableNames"></param> /// <returns></returns> List<TEntity> QueryJoin(Expression<Func<TEntity, bool>> predicate, string[] tableNames); /// <summary> /// 升序查询还是降序查询 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="predicate"></param> /// <param name="keySelector"></param> /// <param name="IsQueryOrderBy"></param> /// <returns></returns> List<TEntity> QueryOrderBy<TKey>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy); /// <summary> /// 升序分页查询还是降序分页 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="pageIndex">第几页</param> /// <param name="pagesize">一页多少条</param> /// <param name="rowcount">返回共多少条</param> /// <param name="predicate">查询条件</param> /// <param name="keySelector">排序字段</param> /// <param name="IsQueryOrderBy">true为升序 false为降序</param> /// <returns></returns> List<TEntity> QueryByPage<TKey>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy); #endregion #region 编辑 /// <summary> /// 通过传入的model加需要修改的字段来更改数据 /// </summary> /// <param name="model"></param> /// <param name="propertys"></param> void Edit(TEntity model, string[] propertys); /// <summary> /// 直接查询之后再修改 /// </summary> /// <param name="model"></param> void Edit(TEntity model); #endregion #region 删除 void Delete(TEntity model, bool isadded); #endregion #region 新增 void Add(TEntity model); #endregion #region 统一提交 int SaverChanges(); #endregion #region 调用存储过程返回一个指定的TResult List<TResult> RunProc<TResult>(string sql, params object[] pamrs); #endregion } }
2、然后实现IBaseRepository接口,在52MVCBlog.Repository程序集中创建BaseRepository类来实现对数据操作的查询、增加、删除、编辑等。
BaseRepository代码:
using _52MVCBlog.IRepository.Base; using _52MVCBlog.Model; using System; using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace _52MVCBlog.Repository.Base { public class BaseRepository<TEntity> : IBaseRepository<TEntity> where TEntity : class { _52MVCBlogDB db = new _52MVCBlogDB(); DbSet<TEntity> _dbSet; public BaseRepository() { _dbSet = db.Set<TEntity>(); } #region 查询 /// <summary> /// 单表查询 /// </summary> /// <param name="predicate"></param> /// <returns></returns> public List<TEntity> QueryWhere(Expression<Func<TEntity, bool>> predicate) { return _dbSet.Where(predicate).ToList(); } /// <summary> /// 多表关联查询 /// </summary> /// <param name="predicate"></param> /// <param name="tableNames"></param> /// <returns></returns> public List<TEntity> QueryJoin(Expression<Func<TEntity, bool>> predicate, string[] tableNames) { if (tableNames == null && tableNames.Any() == false) { throw new Exception("缺少连表名称"); } //DbSet继承DbQuery;DbSet;表示上下文中给定类型的所有实体的集合或可从数据库中查询的给定类型的所有实体的集合。DbQuery表示针对 DbContext 的非泛型 LINQ to Entities 查询。 DbQuery<TEntity> query = _dbSet; foreach (var table in tableNames) { query = query.Include(table); } return query.Where(predicate).ToList(); } /// <summary> /// 升序查询还是降序查询 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="predicate"></param> /// <param name="keySelector"></param> /// <param name="IsQueryOrderBy"></param> /// <returns></returns> public List<TEntity> QueryOrderBy<TKey>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy) { if (IsQueryOrderBy) return _dbSet.Where(predicate).OrderBy(keySelector).ToList(); else return _dbSet.Where(predicate).OrderByDescending(keySelector).ToList(); } /// <summary> /// 升序分页查询还是降序分页 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="pageIndex">第几页</param> /// <param name="pagesize">一页多少条</param> /// <param name="rowcount">返回共多少条</param> /// <param name="predicate">查询条件</param> /// <param name="keySelector">排序字段</param> /// <param name="IsQueryOrderBy">true为升序 false为降序</param> /// <returns></returns> public List<TEntity> QueryByPage<TKey>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy) { rowcount = _dbSet.Count(predicate); if (IsQueryOrderBy) return _dbSet.Where(predicate).OrderBy(keySelector).Skip((pageIndex - 1) * pagesize).Take(pagesize).ToList(); else return _dbSet.Where(predicate).OrderByDescending(keySelector).Skip((pageIndex - 1) * pagesize).Take(pagesize).ToList(); } #endregion #region 编辑 /// <summary> /// 通过传入的model加需要修改的字段来更改数据 /// </summary> /// <param name="model"></param> /// <param name="propertys"></param> public void Edit(TEntity model, string[] propertys) { if (model == null) throw new Exception("实体不能为空"); if(!propertys.Any()) throw new Exception("要修改的属性至少要有一个"); //将model追击到EF容器 DbEntityEntry entry= db.Entry(model); entry.State = EntityState.Unchanged; foreach (var item in propertys) { entry.Property(item).IsModified=true; } //关闭EF对于实体的合法性验证参数 db.Configuration.ValidateOnSaveEnabled = false; } /// <summary> /// 直接查询之后再修改 /// </summary> /// <param name="model"></param> public void Edit(TEntity model) { db.Entry(model).State = EntityState.Modified; } #endregion #region 删除 public void Delete(TEntity model, bool isadded) { if (!isadded) { _dbSet.Attach(model); } _dbSet.Remove(model); } #endregion #region 新增 public void Add(TEntity model) { _dbSet.Add(model); } #endregion #region 统一提交 public int SaverChanges() { return db.SaveChanges(); } #endregion #region 调用存储过程返回一个指定的TResult public List<TResult> RunProc<TResult>(string sql, params object[] pamrs) { return db.Database.SqlQuery<TResult>(sql, pamrs).ToList(); } #endregion } }
三、业务逻辑层父接口和父类创建
1、在52MVCBlog.IService程序集中创建IBaseServices接口
IBaseServices接口代码:
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace _52MVCBlog.IService.Base { public interface IBaseServices<TEntity> where TEntity : class { #region 查询 /// <summary> /// 单表查询 /// </summary> /// <param name="predicate"></param> /// <returns></returns> List<TEntity> QueryWhere(Expression<Func<TEntity, bool>> predicate); /// <summary> /// 多表关联查询 /// </summary> /// <param name="predicate"></param> /// <param name="tableNames"></param> /// <returns></returns> List<TEntity> QueryJoin(Expression<Func<TEntity, bool>> predicate, string[] tableNames); /// <summary> /// 升序查询还是降序查询 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="predicate"></param> /// <param name="keySelector"></param> /// <param name="IsQueryOrderBy"></param> /// <returns></returns> List<TEntity> QueryOrderBy<TKey>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy); /// <summary> /// 升序分页查询还是降序分页 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="pageIndex">第几页</param> /// <param name="pagesize">一页多少条</param> /// <param name="rowcount">返回共多少条</param> /// <param name="predicate">查询条件</param> /// <param name="keySelector">排序字段</param> /// <param name="IsQueryOrderBy">true为升序 false为降序</param> /// <returns></returns> List<TEntity> QueryByPage<TKey>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy); #endregion #region 编辑 /// <summary> /// 通过传入的model加需要修改的字段来更改数据 /// </summary> /// <param name="model"></param> /// <param name="propertys"></param> void Edit(TEntity model, string[] propertys); /// <summary> /// 直接查询之后再修改 /// </summary> /// <param name="model"></param> void Edit(TEntity model); #endregion #region 删除 void Delete(TEntity model, bool isadded); #endregion #region 新增 void Add(TEntity model); #endregion #region 统一提交 int SaverChanges(); #endregion #region 调用存储过程返回一个指定的TResult List<TResult> RunProc<TResult>(string sql, params object[] pamrs); #endregion } }
2、在52MVCBlog.Service程序集创建BaseServices类
using _52MVCBlog.IRepository.Base; using _52MVCBlog.IService.Base; using _52MVCBlog.Repository.Base; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace _52MVCBlog.Service.Base { public class BaseServices<TEntity> : IBaseServices<TEntity> where TEntity : class { private IBaseRepository<TEntity> baseDal = new BaseRepository<TEntity>(); #region 查询 /// <summary> /// 单表查询 /// </summary> /// <param name="predicate"></param> /// <returns></returns> public List<TEntity> QueryWhere(Expression<Func<TEntity, bool>> predicate) { return baseDal.QueryWhere(predicate); } /// <summary> /// 多表关联查询 /// </summary> /// <param name="predicate"></param> /// <param name="tableNames"></param> /// <returns></returns> public List<TEntity> QueryJoin(Expression<Func<TEntity, bool>> predicate, string[] tableNames) { return baseDal.QueryJoin(predicate, tableNames); } /// <summary> /// 升序查询还是降序查询 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="predicate"></param> /// <param name="keySelector"></param> /// <param name="IsQueryOrderBy"></param> /// <returns></returns> public List<TEntity> QueryOrderBy<TKey>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy) { return baseDal.QueryOrderBy(predicate, keySelector, IsQueryOrderBy); } /// <summary> /// 升序分页查询还是降序分页 /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="pageIndex">第几页</param> /// <param name="pagesize">一页多少条</param> /// <param name="rowcount">返回共多少条</param> /// <param name="predicate">查询条件</param> /// <param name="keySelector">排序字段</param> /// <param name="IsQueryOrderBy">true为升序 false为降序</param> /// <returns></returns> public List<TEntity> QueryByPage<TKey>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy) { return baseDal.QueryByPage(pageIndex, pagesize, out rowcount, predicate, keySelector, IsQueryOrderBy); } #endregion #region 编辑 /// <summary> /// 通过传入的model加需要修改的字段来更改数据 /// </summary> /// <param name="model"></param> /// <param name="propertys"></param> public void Edit(TEntity model, string[] propertys) { baseDal.Edit(model, propertys); } /// <summary> /// 直接查询之后再修改 /// </summary> /// <param name="model"></param> public void Edit(TEntity model) { baseDal.Edit(model); } #endregion #region 删除 public void Delete(TEntity model, bool isadded) { baseDal.Delete(model, isadded); } #endregion #region 新增 public void Add(TEntity model) { baseDal.Add(model); } #endregion #region 统一提交 public int SaverChanges() { return baseDal.SaverChanges(); } #endregion #region 调用存储过程返回一个指定的TResult public List<TResult> RunProc<TResult>(string sql, params object[] pamrs) { return baseDal.RunProc<TResult>(sql, pamrs); } #endregion } }
到目前为止数据库、仓储层、业务逻辑层的父类和父接口都实现了,下一篇博文就在UI层怎么调用
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!