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. kafka消费者如何才能从头开始消费某个topic的全量数据

    消费者要从头开始消费某个topic的全量数据,需要满足2个条件(spring-kafka): (1)使用一个全新的"group.id"(就是之前没有被任何消费者使用过); (2)指 ...

  2. c与c++相互调用机制分析与实现

    c++通常被称为Better c,多数是因为c++程序可以很简单的调用c函数,语法上基本实现兼容.最常用的调用方式就是c++模块调用c实现的dll导出函数,很简单的用法,使用extern " ...

  3. java中的数据结构[copy]

    转自http://developer.51cto.com/art/201107/273003.htm java版数据结构与算法,希望对你有帮助. 线性表,链表,哈希表是常用的数据结构,在进行Java开 ...

  4. Pyperclip – A cross-platform clipboard module for Python

    Usage is simple: import pyperclip pyperclip.copy('The text to be copied to the clipboard.') spam = p ...

  5. Python 入门网络爬虫之精华版

    Python 入门网络爬虫之精华版 转载 宁哥的小站,总结的不错 Python学习网络爬虫主要分3个大的版块:抓取,分析,存储 另外,比较常用的爬虫框架Scrapy,这里最后也详细介绍一下. 首先列举 ...

  6. [转]PowerDesigner中name和code取消自动关联

    PowerDesigner中,但修改了某个字段的name,其code也跟着修改,这个问题很讨厌,因为一般来说,name是中文的,code是字段名. 解决方法如下: 1.选择Tools->Gene ...

  7. 【微信小程序】scroll-view与Page下拉冲突

    需求:主界面是个列表.列表可以纵向滑动,下拉添加新的条目Item.每个条目Item可以横向滑动. 发现做下拉时,用Page的enablePullDownRefresh和scroll-view条目的横向 ...

  8. 宇宙最强spacemacs

    这个标题背后的潜台词其实是:逼格是什么炼成的? 此处省略一万字. Emacs就不多说了,神之编辑器,但其快捷键实在是....Evil.好啦,现在来了Spacemacs,结合Vim与Emacs二者的优点 ...

  9. CycleGAN 各种变变变

    转载自 简单介绍了一下GAN和DCGAN的原理.以及如何使用Tensorflow做一个简单的生成图片的demo. Ian Goodfellow对GAN一系列工作总结的ppt,确实精彩,推荐:独家 | ...

  10. 如何在CentOS 6.5上升级PHP

    CentOS 6.5上默认安装PHP 5.3.因为后台网站无法正确运行在PHP 5.3上,所以计划将PHP升级到开发平台一样的版本PHP 5.5.为了方便,我们采用YUM的方式升级PHP 工具/原料 ...