1:项目结构

2:每层添加对其他层的引用,这里我们把除了Web层之外的所有的层生成的文件都放到解决方案下的Library文件夹下,然后每个项目分别来引用里面的dll项目文件.

我们在Model项目上,右键属性->生成-> 在下面的输出里面,选择上一级的 Library文件夹

2.2 我们调整项目的生成顺序 ,在解决方案或者是任意项目上右键,选择 生成依赖项,调整各个项目的依赖,这样的目的就是调整项目的生成顺序.

注意,这里你选择依赖项,并没有给项目与项目之间增加了dll的引用,只是单纯的修改了他们的项目生成顺序而已.

BLL层依赖 Common层,Model层

Common依赖 Model层

Repository依赖 Model和Common层

BLL依赖 Model,Common,Repository层

UI层依赖上面的所有的层,那么调整完毕后的项目生成顺序如下

  最后的生成顺序是 

我们把整个项目编译一下,看看各个项目的生成顺序.

2.3 我们对各个项目进行引用.

BLL层引用 Library文件夹下        Common层,Model层  生成的dll文件

Common 引用 Library文件夹下   Model层  生成的dll文件

Repository 引用 Library文件夹下  Model和Common层  生成的dll文件

BLL引用  Library文件夹下           Model,Common,Repository层  生成的dll文件

UI 层 引用 Library 文件夹下   Model,Common,BLL层 (不用引用 Repository层) 生成的dll文件

3: 在 Model层,添加EF实体框架,并且把 app.config 里面的链接字符串 拷贝到 UI层里面的 web.config 里面

4:开始编写 Repository 数据库访问层的代码

4.1 编写UserInfoRepository

UserInfoRepository 用户表的数据库访问代码/// <summary>
/// 用户表操作类
/// </summary>
public class UserInfoRepository
{ public UserInfoRepository()
{ }
private ModelFirstDemoEntities db = new ModelFirstDemoEntities(); #region 增加实体 /// <summary>
/// 增加实体
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public UserInfo AddEntity(UserInfo model)
{
db.UserInfo.Add(model);
db.SaveChanges();
return model;
} #endregion #region 根据传进来的条件,进行删除操作 int Delete(Expression<Func<UserInfo, bool>> whereLambda) /// <summary>
/// 根据传进来的条件,进行删除操作 int Delete(Expression<Func<UserInfo, bool>> whereLambda)
/// </summary>
/// <param name="whereLambda">删除的条件</param>
/// <returns></returns>
public int Delete(Expression<Func<UserInfo, bool>> whereLambda)
{
var deleteList = db.UserInfo.Where(whereLambda).ToList();
deleteList.ForEach(u => db.UserInfo.Remove(u));
return db.SaveChanges();
} #endregion #region 根据实体需要修改的属性来修改实体的值 int Update(UserInfo model, parameter string[] propertyName) /// <summary>
/// 根据实体需要修改的属性来修改实体的值 int Update(UserInfo model, string[] propertyName)
/// </summary>
/// <param name="model">修改的实体</param>
/// <param name="propertyName">将要修改的属性</param>
/// <returns>返回影响的行数</returns>
public int Modif(UserInfo model, string[] propertyName)
{
DbEntityEntry entry = db.Entry(model);
entry.State = EntityState.Unchanged; //这里设置传进来要修改的model的状态为 未修改状态 foreach (var proName in propertyName)
{
entry.Property(proName).IsModified = true; //然后针对具体要修改的属性设置为修改
}
return db.SaveChanges();
} #endregion #region 批量修改 根据实体需要修改的属性来修改实体的值 /// <summary>
/// 批量修改 根据实体需要修改的属性来修改实体的值
/// 调用实例UserInfo newUserInfo=new UserInfo(){ UserName = "新的名字"};
/// ModifBy(newUserInfo, u => u.Id > 1, "UserName");
/// </summary>
/// <param name="newModel">新的值</param>
/// <param name="whereLambda">查询要修改的数据</param>
/// <param name="propertyName">将要修改的属性</param>
/// <returns>返回影响的行数</returns>
public int ModifBy(UserInfo newModel, Expression<Func<UserInfo, bool>> whereLambda, params string[] propertyName)
{
List<UserInfo> modiList = db.UserInfo.Where(whereLambda).ToList(); Type type = typeof(UserInfo); //获取类型
List<PropertyInfo> propertyInfos= type.GetProperties().ToList();
Dictionary<string,PropertyInfo> dictionary=new Dictionary<string, PropertyInfo>();
foreach (var property in propertyInfos)
{
if (propertyName.Contains(property.Name))
{
dictionary.Add(property.Name,property);
}
} foreach (var oldUserInfo in modiList)
{
foreach (var proName in propertyName)
{
PropertyInfo property = dictionary[proName];
object val = property.GetValue(newModel, null); //根据属性,来从新的model中 获取数据 比如是获取
property.SetValue(oldUserInfo, val, null); //根据这个属性 来修改值
}
} return db.SaveChanges();
} #endregion #region 查询 不带分页 public List<UserInfo> GetListBy(Expression<Func<UserInfo,bool>> whereLambda)
{
return db.UserInfo.Where(whereLambda).ToList();
}
#endregion #region 带分页和正序倒序的查询 /// <summary>
/// 带分页和正序倒序的查询
/// </summary>
/// <typeparam name="TKey">这个可以不写,编译器会自动推断你orderby的是哪个列是什么类型(int还是string类型)</typeparam>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderByLambda">排序条件</param>
/// <param name="pagesize">分页大小</param>
/// <param name="pageindex">分页页码</param>
/// <param name="isDEsc">是否倒序,默认是否(也就是说默认我们是用正序从小到大)</param>
/// <returns></returns>
public List<UserInfo> GetListBy<TKey>(Expression<Func<UserInfo, bool>> whereLambda,
Expression<Func<UserInfo, TKey>> orderByLambda, int pagesize = 10, int pageindex = 1, bool isDEsc = false)
{
if (isDEsc)
{
return db.UserInfo.Where(whereLambda).OrderByDescending(orderByLambda)
.Skip(pagesize * (pageindex - 1)).Take(pagesize).ToList();
}
else
{
return db.UserInfo.Where(whereLambda).OrderBy(orderByLambda)
.Skip(pagesize * (pageindex - 1)).Take(pagesize).ToList();
}
} #endregion }

4.2 考虑到我们有多个表,每个表都有这些增删改查,所以我们重构一下,写一个 BaseRepository 类

BaseRepositorypublic class BaseRepository<T> where T : class ,new()
{
private ModelFirstDemoEntities db = new ModelFirstDemoEntities(); #region 增加实体 /// <summary>
/// 增加实体
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public T AddEntity(T model)
{
db.Set<T>().Add(model);
db.SaveChanges();
return model;
} #endregion #region 根据传进来的条件,进行删除操作 int Delete(Expression<Func<T, bool>> whereLambda) /// <summary>
/// 根据传进来的条件,进行删除操作 int Delete(Expression<Func<T, bool>> whereLambda)
/// </summary>
/// <param name="whereLambda">删除的条件</param>
/// <returns></returns>
public int Delete(Expression<Func<T, bool>> whereLambda)
{
var deleteList = db.Set<T>().Where(whereLambda).ToList();
deleteList.ForEach(u => db.Set<T>().Remove(u));
return db.SaveChanges();
} #endregion #region 根据实体需要修改的属性来修改实体的值 int Update(T model, parameter string[] propertyName) /// <summary>
/// 根据实体需要修改的属性来修改实体的值 int Update(T model, string[] propertyName)
/// </summary>
/// <param name="model">修改的实体</param>
/// <param name="propertyName">将要修改的属性</param>
/// <returns>返回影响的行数</returns>
public int Modif(T model, string[] propertyName)
{
DbEntityEntry entry = db.Entry(model);
entry.State = EntityState.Unchanged; //这里设置传进来要修改的model的状态为 未修改状态 foreach (var proName in propertyName)
{
entry.Property(proName).IsModified = true; //然后针对具体要修改的属性设置为修改
}
return db.SaveChanges();
} #endregion #region 批量修改 根据实体需要修改的属性来修改实体的值 /// <summary>
/// 批量修改 根据实体需要修改的属性来修改实体的值
/// 调用实例T newT=new T(){ UserName = "新的名字"};
/// ModifBy(newT, u => u.Id > 1, "UserName");
/// </summary>
/// <param name="newModel">新的值</param>
/// <param name="whereLambda">查询要修改的数据</param>
/// <param name="propertyName">将要修改的属性</param>
/// <returns>返回影响的行数</returns>
public int ModifBy(T newModel, Expression<Func<T, bool>> whereLambda, params string[] propertyName)
{
List<T> modiList = db.Set<T>().Where(whereLambda).ToList(); Type type = typeof(T); //获取类型
List<PropertyInfo> propertyInfos = type.GetProperties().ToList();
Dictionary<string, PropertyInfo> dictionary = new Dictionary<string, PropertyInfo>();
foreach (var property in propertyInfos)
{
if (propertyName.Contains(property.Name))
{
dictionary.Add(property.Name, property);
}
} foreach (var oldT in modiList)
{
foreach (var proName in propertyName)
{
PropertyInfo property = dictionary[proName];
object val = property.GetValue(newModel, null); //根据属性,来从新的model中 获取数据 比如是获取
property.SetValue(oldT, val, null); //根据这个属性 来修改值
}
} return db.SaveChanges();
} #endregion #region 查询 不带分页 public List<T> GetListBy(Expression<Func<T, bool>> whereLambda)
{
return db.Set<T>().Where(whereLambda).ToList();
}
#endregion #region 带分页和正序倒序的查询 /// <summary>
/// 带分页和正序倒序的查询
/// </summary>
/// <typeparam name="TKey">这个可以不写,编译器会自动推断你orderby的是哪个列是什么类型(int还是string类型)</typeparam>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderByLambda">排序条件</param>
/// <param name="pagesize">分页大小</param>
/// <param name="pageindex">分页页码</param>
/// <param name="isDEsc">是否倒序,默认是否(也就是说默认我们是用正序从小到大)</param>
/// <returns></returns>
public List<T> GetListBy<TKey>(Expression<Func<T, bool>> whereLambda,
Expression<Func<T, TKey>> orderByLambda, int pagesize = 10, int pageindex = 1, bool isDEsc = false)
{
if (isDEsc)
{
return db.Set<T>().Where(whereLambda).OrderByDescending(orderByLambda)
.Skip(pagesize * (pageindex - 1)).Take(pagesize).ToList();
}
else
{
return db.Set<T>().Where(whereLambda).OrderBy(orderByLambda)
.Skip(pagesize * (pageindex - 1)).Take(pagesize).ToList();
}
} #endregion
}

5 .我们编写 BLL层 业务逻辑层的代码, 首先是  UserInfoService.cs  ,由于 业务逻辑层也是有很多代码,所以我们也是抽象出一个 BaseService.cs 父类出来

BaseServicenamespace Joey.BLL
{
public class BaseService<T> where T : class ,new()
{
BaseRepository<T> dal =new BaseRepository<T>(); #region 增加实体 /// <summary>
/// 增加实体
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public T AddEntity(T model)
{
return dal.AddEntity(model);
} #endregion #region 根据传进来的条件,进行删除操作 int Delete(Expression<Func<T, bool>> whereLambda) /// <summary>
/// 根据传进来的条件,进行删除操作 int Delete(Expression<Func<T, bool>> whereLambda)
/// </summary>
/// <param name="whereLambda">删除的条件</param>
/// <returns></returns>
public int Delete(Expression<Func<T, bool>> whereLambda)
{
return dal.Delete(whereLambda);
} #endregion #region 根据实体需要修改的属性来修改实体的值 int Update(T model, parameter string[] propertyName) /// <summary>
/// 根据实体需要修改的属性来修改实体的值 int Update(T model, string[] propertyName)
/// </summary>
/// <param name="model">修改的实体</param>
/// <param name="propertyName">将要修改的属性</param>
/// <returns>返回影响的行数</returns>
public int Modif(T model, string[] propertyName)
{
return dal.Modif(model, propertyName);
} #endregion #region 批量修改 根据实体需要修改的属性来修改实体的值 /// <summary>
/// 批量修改 根据实体需要修改的属性来修改实体的值
/// 调用实例T newT=new T(){ UserName = "新的名字"};
/// ModifBy(newT, u => u.Id > 1, "UserName");
/// </summary>
/// <param name="newModel">新的值</param>
/// <param name="whereLambda">查询要修改的数据</param>
/// <param name="propertyName">将要修改的属性</param>
/// <returns>返回影响的行数</returns>
public int ModifBy(T newModel, Expression<Func<T, bool>> whereLambda, params string[] propertyName)
{
return ModifBy(newModel, whereLambda, propertyName);
} #endregion #region 查询 不带分页 public List<T> GetListBy(Expression<Func<T, bool>> whereLambda)
{
return dal.GetListBy(whereLambda);
}
#endregion #region 带分页和正序倒序的查询 /// <summary>
/// 带分页和正序倒序的查询
/// </summary>
/// <typeparam name="TKey">这个可以不写,编译器会自动推断你orderby的是哪个列是什么类型(int还是string类型)</typeparam>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderByLambda">排序条件</param>
/// <param name="pagesize">分页大小</param>
/// <param name="pageindex">分页页码</param>
/// <param name="isDEsc">是否倒序,默认是否(也就是说默认我们是用正序从小到大)</param>
/// <returns></returns>
public List<T> GetListBy<TKey>(Expression<Func<T, bool>> whereLambda,
Expression<Func<T, TKey>> orderByLambda, int pagesize = 10, int pageindex = 1, bool isDEsc = false)
{
return dal.GetListBy(whereLambda, orderByLambda, pagesize, pageindex, isDEsc);
} #endregion
}
}

然后我们的UserInfoService.cs  用户表业务逻辑操作类 只需要继承一下这业务基类就可以了

但是这里有个问题,如果是我们 UserInfoRepository 用户表的数据库访问层,有一个单独的功能,只是针对这个表的(也就是BaseRepository里面没有这个功能),那么我们在 UserInfoService里面,由于继承的是 BaseService 父类,而父类里面的DAL层是使用的 BaseRepository (数据库访问层的基类),那么 UserInfoService里面的dal层也是 BaseRepository, 这样就调用不到  UserInfoRepository 里面的方法了

解决方法就是在 BaseService里面,把 添加一个  抽象方法 SetCurrentRepository ,专门由子类进行重构,这个方法的作用就是重写父类的 CurrnetRepository来进行new一个数据操作子类

6. 我们在UI层 进行调用

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查的更多相关文章

  1. Spring Boot入门系列(六)如何整合Mybatis实现增删改查

    前面介绍了Spring Boot 中的整合Thymeleaf前端html框架,同时也介绍了Thymeleaf 的用法.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/z ...

  2. ASP.NET Identity系列02,在ASP.NET MVC中增删改查用户

    本篇体验在ASP.NET MVC中使用ASP.NET Identity增删改查用户. 源码在这里:https://github.com/darrenji/UseIdentityCRUDUserInMV ...

  3. 初次尝试PHP——一个简单的对数据库操作的增删改查例子

    第一次学习PHP,很多人说PHP是最好的语言,学习了一点点,还不敢说这样的话,不过确实蛮好用的. 做了一个简单的对数据库的增删改查的操作,主要是将四种操作写成了独立的函数,之后直接调用函数.以下是代码 ...

  4. jsp-2 简单的servlet连接mysql数据库 增删改查

    连接mysql数据库的操作 有增删改查 用的包有 commons-lang3-3.5 mysql-connector-java-5.1.40-bin 但是实际上也就是 数据查询和数据处理两种 所以对数 ...

  5. 2.关于QT中数据库操作,简单数据库连接操作,数据库的增删改查,QSqlTableModel和QTableView,事务操作,关于QItemDelegate 代理

     Linux下的qt安装,命令时:sudoapt-get install qt-sdk 安装mysql数据库,安装方法参考博客:http://blog.csdn.net/tototuzuoquan ...

  6. asp.net mvc 三层加EF 登录注册 增删改查

    首先打开vs软件新建项目创建web中的mvc项目再右击解决方案创建类库项目分别创建DAL层和BLL层再把DAL层和BLL层的类重命名在mvc项目中的Models文件夹创建model类在DAL创建ADO ...

  7. popup的简单应用举例(具体在增删改查组件中用到)以及补充的知识点

    一.首先说一下自执行函数 1. 立即执行函数是什么?也就是匿名函数 立即执行函数就是 声明一个匿名函数 马上调用这个匿名函数 2.popup的举例 点击,弹出一个新的窗口.保存完事,页面不刷新数据就返 ...

  8. JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(三):两个Viewmodel搞定增删改查

    前言:之前博主分享过knockoutJS和BootstrapTable的一些基础用法,都是写基础应用,根本谈不上封装,仅仅是避免了html控件的取值和赋值,远远没有将MVVM的精妙展现出来.最近项目打 ...

  9. JS组件系列——又一款MVVM组件:Vue(一:30分钟搞定前端增删改查)

    前言:关于Vue框架,好几个月之前就听说过,了解一项新技术之后,总是处于观望状态,一直在犹豫要不要系统学习下.正好最近有点空,就去官网了解了下,看上去还不错的一个组件,就抽空研究了下.最近园子里vue ...

随机推荐

  1. ffmpeg转码参数设置

    ffmpeg用了很久了,也没有想写点什么. 刚接触ffmpeg也是有大量的不理解的地方,不过慢慢的了解多了基本上都是可以使用的. 本文主要介绍如何使用ffmpeg.exe进行转码.编译好的ffmpeg ...

  2. oracle Plsql 执行update或者delete时卡死问题解决办法

    PLSQL删除记录 delete from OT_Table 程序一直在执行... 原因: 在执行  修改 的时候没有commit,oracle将该记录锁住了. 可以通过以下办法解决: 先查询锁定记录 ...

  3. 实现基于最近邻内插和双线性内插的图像缩放C++实现

    平时我们写图像处理的代码时,如果需要缩放图片,我们都是直接调用图像库的resize函数来完成图像的缩放.作为一个机器视觉或者图像处理算法的工作者,图像缩放代码的实现应该是必须掌握的.在众多图像缩放算法 ...

  4. Windows系统盘瘦身指南

    [本文出自天外归云的博客园] Windows系统的C盘空间越来越小,按以下四步进行清理,还你6个G: 1.开启腾讯管家之类的软件进行第一轮垃圾清理: 2.删除以下文件夹,"C:\Progra ...

  5. Cpu表现出正弦曲线

    #include <windows.h> #include <math.h> int main(void) { SetThreadAffinityMask(GetCurrent ...

  6. 【转】 Java中的变量赋值和参数传递

    原文地址:http://blog.csdn.net/whmii/article/details/3363667 变量赋值和参数传递是java中两个容易让人迷惑的问题.对于原始类型(primitives ...

  7. [转]MYSQL 与 Oracle 之间的数据类型转换

    原文地址:http://www.cnblogs.com/guyueyanzi/archive/2010/02/27/1674788.html Table 2-4 Default Data Type M ...

  8. Spring框架中InitializingBean执行顺序

    本文转自:https://www.cnblogs.com/yql1986/p/4084888.html package org.test.InitializingBean; 2 3 import or ...

  9. Java多线程——sychronized

    概述 关键字synchronized的作用是实现线程间的同步.它的工作是对同步的代码加锁,使得每一次,只能有一个线程进入同步块,从而保证线程间的安全性. 直接作用于实例方法(普通同步方法):对当前实例 ...

  10. 【Unity Shader】二、顶点函数(vertex)和片元函数(fragment)传递数据,及各阶段可使用的语义(semantic)

    学习资料:http://www.sikiedu.com/course/37/task/433/show 本节学习目标: 学习Shader中结构体struct的使用. 学习在片元函数(vertex)和顶 ...