前言

     从上篇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类:

 namespace Wchl.WMBlog.Model.Models
{
public 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 Wchl.WMBlog.Model.Maps
{
public class sysUserInfoMap: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);
}
}
}

关于EntityTypeConfiguration类的用法,大家可以去看看博客园里面一些介绍文章,HasKey设置主键,HasMaxLength字段最大长度。

5、在控制台中创建数据库脚本 Enable-Migrations

6、修改Configuration类配置

7、在WMBlogDB类中重写OnModelCreating方法

重写OnModelCreating方法:

         protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//移除表名为复数
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
//自动添加实现EntityTypeConfiguration的类
modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());
base.OnModelCreating(modelBuilder);
}

二、仓储层建设

1、在Wchl.WMBlog.IRepository中创建一个类,做为操作数据的父接口IBaseRepository,这里使用泛型来创建

IBaseRepository接口

 namespace Wchl.WMBlog.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接口,在Wchl.WMBlog.Repository程序集中创建BaseRepository类来实现对数据操作的查询、增加、删除、编辑等。

BaseRepository类

 namespace Wchl.WMBlog.Repository.Base
{
public class BaseRepository<TEntity>: IBaseRepository<TEntity> where TEntity:class
{
WMBlogDB db = new WMBlogDB(); 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("缺少连表名称");
} 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();
}
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() == false)
{
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、在Wchl.WMBlog.IServices程序集中创建IBaseServices接口

IBaseServices接口:

 namespace Wchl.WMBlog.IServices.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、在Wchl.WMBlog.Services程序集创建BaseServices类

BaseServices类

 namespace Wchl.WMBlog.Services.Base
{
public class BaseServices<TEntity>: IBaseServices<TEntity> where TEntity:class
{
public 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搭建框架(1),EF Code frist、实现泛型数据仓储以及业务逻辑的更多相关文章

  1. 从零开始,搭建博客系统MVC5+EF6搭建框架(4)上,前后台页面布局页面实现,介绍使用的UI框架以及JS组件

    一.博客系统进度回顾以及页面设计 1.1页面设计说明 紧接前面基础基本完成了框架搭建,现在开始设计页面,前台页面设计我是模仿我博客园的风格来设计的,后台是常规的左右布局风格. 1.2前台页面风格 主页 ...

  2. 从零开始,搭建博客系统MVC5+EF6搭建框架(5),博客详情页、留言、轮播图管理、右侧统计博文

    一.博客系统进度回顾 上一遍博客介绍到,系统已经实现到了发布以及前台布局展示,接下来就是实现一些,详情页,留言.轮播图管理.右侧博文统计信息实现. 二.博客系统详情页实现 2.1先来看看详情页展示的效 ...

  3. 从零开始,搭建博客系统MVC5+EF6搭建框架(4)下,前后台布局实现、发布博客以及展示。

    一.博客系统进度回顾 目前已经完成了,前台展示,以及后台发布的功能,最近都在做这个,其实我在国庆的时候就可以弄完的,但是每天自己弄,突然最后国庆2天,连电脑都不想碰,所以就一直拖着,上一篇写了前端实现 ...

  4. 从零开始,搭建博客系统MVC5+EF6搭建框架(3),添加Nlog日志、缓存机制(MemoryCache、RedisCache)、创建控制器父类BaseController

    一.回顾系统进度以及本章概要 目前博客系统已经数据库创建.以及依赖注入Autofac集成,接下来就是日志和缓存集成,这里日志用的是Nlog,其实还有其他的日志框架如log4,这些博客园都有很多介绍,这 ...

  5. 从零开始,搭建博客系统MVC5+EF6搭建框架(2),测试添加数据、集成Autofac依赖注入

    一.测试仓储层.业务层是否能实现对数据库表的操作 1.创建IsysUserInfoRepository接口来继承IBaseRepository父接口 namespace Wchl.WMBlog.IRe ...

  6. 【干货】利用MVC5+EF6搭建博客系统(一)EF Code frist、实现泛型数据仓储以及业务逻辑

    习MVC有一段时间了,决定自己写一套Demo了,写完源码再共享. PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可. 一.框架搭建 二.创建数据库 1.创建一个空的EF code fr ...

  7. Django快速搭建博客系统

    Django快速搭建博客系统 一.开发环境 Windows 7(64bit) python 3.6   https://www.python.org/ Django 2.0  https://www. ...

  8. day14搭建博客系统项目

    day14搭建博客系统项目 1.下载代码包 [root@web02 opt]# git clone https://gitee.com/lylinux/DjangoBlog.git 2.使用pid安装 ...

  9. 【干货】利用MVC5+EF6搭建博客系统(四)(上)前后台页面布局页面实现,介绍使用的UI框架以及JS组件

    一.博客系统进度回顾以及页面设计 1.1页面设计说明 紧接前面基础基本完成了框架搭建,现在开始设计页面,前台页面设计我是模仿我博客园的风格来设计的,后台是常规的左右布局风格. 1.2前台页面风格 主页 ...

随机推荐

  1. JS请求服务器并使页面跳转(转)

    前段时间在项目中用到了前台框架EasyUI,各种组件都是差不多都是用js来渲染的,这样一些页面请求就必须用js代码来写. 但是js请求就不和html请求的玩法不怎么相同,比如我要向服务器发送一个请求然 ...

  2. review简历之感想和建议

    最近帮很多朋友review他们的简历,总结起来存在以下问题: 1,简历太多页了.请尽量不超过两页.一般地,每个hr阅读简历的时间大概在20s甚至更少,写那么多页不仅毫无必要,而且有害. 而且我怀疑一般 ...

  3. checkbox和文字对齐

    <style type="text/css"> input{vertical-align:middle; margin-top:0;} </style>

  4. .Net 跨平台可移植类库PCL可用于任何平台包括Mono

    Microsoft 在 .NET Framework 4 中添加了一个名为可移植类库 (PCL) 的新功能. 利用 PCL,您可以有选择性地面向 .NET Framework.Silverlight ...

  5. Functional Programming without Lambda - Part 2 Lifting, Functor, Monad

    Lifting Now, let's review map from another perspective. map :: (T -> R) -> [T] -> [R] accep ...

  6. 一个上好的C# http/https类

    直接Copy拿去用吧: 新的 tls 协议需要新的.net版本, tls 至少更新到.net4吧,尽量用最新的.net! 不然出错了就折腾... using System; using System. ...

  7. 关于ie11 的开发者工具

    win7旗舰系统64为,更新ie11: 新安装了ie11浏览器,安装以后发现原来可以正常使用的开发者工具不能使用,提示 Imposible use F12 Developer Tools (Excep ...

  8. C#设计模式系列:建造者模式(Builder)

    1.建造者模式简介 1.1>.定义 建造者模式(Builder)将复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. 1.2>.使用频率 中低 1.3>.原型模式应用 ...

  9. javascript运动系列第四篇——抖动

    × 目录 [1]原理介绍 [2]代码实现 [3]实例应用 前面的话 在运动系列中,前面分别介绍了匀速运动.变速运动和曲线运动.下面介绍一种特殊的运动形式——抖动 原理介绍 抖动其实是往复运动的一种特殊 ...

  10. .Net 转战 Android 4.4 日常笔记(5)--新软件Android Studio 0.5.8安装与配置及问题解决

    说真心话,Eclipse跟我们.net的VS比起来就是屌丝比高富帅,一切都是那么的难用,速度慢得我无法忍受 于是想试试Google钦点的Android Studio IDE工具,这跟ADT一样也是一套 ...