【干货】利用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();
this.Property(u => u.uLoginPWD).HasMaxLength();
this.Property(u => u.uRealName).HasMaxLength();
}
}
}
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 - ) * pagesize).Take(pagesize).ToList();
else
return _dbSet.Where(predicate).OrderByDescending(keySelector).Skip((pageIndex - ) * 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层怎么调用
【干货】利用MVC5+EF6搭建博客系统(一)EF Code frist、实现泛型数据仓储以及业务逻辑的更多相关文章
- 【干货】利用MVC5+EF6搭建博客系统(四)(上)前后台页面布局页面实现,介绍使用的UI框架以及JS组件
一.博客系统进度回顾以及页面设计 1.1页面设计说明 紧接前面基础基本完成了框架搭建,现在开始设计页面,前台页面设计我是模仿我博客园的风格来设计的,后台是常规的左右布局风格. 1.2前台页面风格 主页 ...
- 【干货】利用MVC5+EF6搭建博客系统(四)(下)前后台布局实现、发布博客以及展示
二.博客系统后台布局实现 2.1.这里所用的是MVC的布局页来实现的,后台主要分为三部分:导航.菜单.主要内容 代码实现: 这里把后台单独放在一个区域里面,所以我这里建立一个admin的区域 在布局页 ...
- 【干货】利用MVC5+EF6搭建博客系统(三)添加Nlog日志、缓存机制(MemoryCache、RedisCache)、创建控制器父类BaseController
PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可. 一.回顾系统进度以及本章概要 目前博客系统已经数据库创建.以及依赖注入Autofac集成,接下来就是日志和缓存集成,这里日志用的是N ...
- 【干货】利用MVC5+EF6搭建博客系统(二)测试添加数据、集成Autofac依赖注入
PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可. 一.测试仓储层.业务层是否能实现对数据库表的操作 1.在52MVCBlog.IRepository程序集下创建IsysUserInf ...
- 利用MVC5+EF6搭建博客系统
https://www.cnblogs.com/wyt007/p/7880137.html
- 从零开始,搭建博客系统MVC5+EF6搭建框架(1),EF Code frist、实现泛型数据仓储以及业务逻辑
前言 从上篇30岁找份程序员的工作(伪程序员的独白),文章开始,我说过我要用我自学的技术,来搭建一个博客系统,也希望大家给点意见,另外我很感谢博客园的各位朋友们,对我那篇算是自我阶段总结文章 ...
- Django快速搭建博客系统
Django快速搭建博客系统 一.开发环境 Windows 7(64bit) python 3.6 https://www.python.org/ Django 2.0 https://www. ...
- day14搭建博客系统项目
day14搭建博客系统项目 1.下载代码包 [root@web02 opt]# git clone https://gitee.com/lylinux/DjangoBlog.git 2.使用pid安装 ...
- 从零开始,搭建博客系统MVC5+EF6搭建框架(4)上,前后台页面布局页面实现,介绍使用的UI框架以及JS组件
一.博客系统进度回顾以及页面设计 1.1页面设计说明 紧接前面基础基本完成了框架搭建,现在开始设计页面,前台页面设计我是模仿我博客园的风格来设计的,后台是常规的左右布局风格. 1.2前台页面风格 主页 ...
随机推荐
- 磨人的Fragment的转换
磨人的Fragment的转换 本次任务是 程序运行之后将第一个Fragment加载出来 然后点击"SHOW NEXT PAGE"切换到第二个Fragment 当再次点击按钮时下方出 ...
- Redis详细讲解(Redis原理,Redis安装,Redis配置,Redis使用,Redis命令)
一.Redis介绍 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发 ...
- 复习支持向量机(SVM)没空看书时,掌握下面的知识就够了
支持向量机(support vector machines, SVM)是一种二类分类模型.它的基本模型是定义在特征空间上的间隔最大的线性分类器:支持向量机还包括核技巧,这使它成为实质上的非线性分类器. ...
- k8s对接ceph存储
前提条件:已经部署好ceph集群 本次实验由于环境有限,ceph集群是部署在k8s的master节点上的 一.创建ceph存储池 在ceph集群的mon节点上执行以下命令: ceph osd pool ...
- cp/tar/用c语言编写程序 实现cp命令的效果
1.cp (拷贝) 已存在文件路径 要拷贝的文件路径 实现cp命令的代码如下: #include <stdio.h> //因为要在命令中得到两个路径,所以要用到main函数的两个参数 i ...
- recyclerview刷新
https://blog.csdn.net/leejizhou/article/details/51179233 RecyclerView之更新UI数据的高级用法 https://www.cnblog ...
- 安装virtualbox出现2503、2502的错误提示解决方法
安装virtualbox右键选择以管理员的身份打开即可
- JavaScript复习笔记——数据类型
1.undefined 使用var声明但未对其进行初始化时,这个变量的值就是undefined. 对未被初始化的值使用typeof会返回undefined值,而对未声明的变量执行typeof操作同样也 ...
- 记录一下msf的学习使用
刚刚用Metasploit Pro scan了一下云端服务器.RHOST直接输IP就好. 得到反馈如下: [*] [2019.04.04-14:27:35] Scan initiated: Speed ...
- spring boot 入门及示例
需要环境:eclipse4.7.3 + jdk1.8 +maven3.6.1 + tomcat(web需要) spring boot官网介绍:https://spring.io/guides/gs/s ...