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) 简单三层的搭配(泛型) 实现 增删改查的更多相关文章
-
Spring Boot入门系列(六)如何整合Mybatis实现增删改查
前面介绍了Spring Boot 中的整合Thymeleaf前端html框架,同时也介绍了Thymeleaf 的用法.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/z ...
-
ASP.NET Identity系列02,在ASP.NET MVC中增删改查用户
本篇体验在ASP.NET MVC中使用ASP.NET Identity增删改查用户. 源码在这里:https://github.com/darrenji/UseIdentityCRUDUserInMV ...
-
初次尝试PHP——一个简单的对数据库操作的增删改查例子
第一次学习PHP,很多人说PHP是最好的语言,学习了一点点,还不敢说这样的话,不过确实蛮好用的. 做了一个简单的对数据库的增删改查的操作,主要是将四种操作写成了独立的函数,之后直接调用函数.以下是代码 ...
-
jsp-2 简单的servlet连接mysql数据库 增删改查
连接mysql数据库的操作 有增删改查 用的包有 commons-lang3-3.5 mysql-connector-java-5.1.40-bin 但是实际上也就是 数据查询和数据处理两种 所以对数 ...
-
2.关于QT中数据库操作,简单数据库连接操作,数据库的增删改查,QSqlTableModel和QTableView,事务操作,关于QItemDelegate 代理
Linux下的qt安装,命令时:sudoapt-get install qt-sdk 安装mysql数据库,安装方法参考博客:http://blog.csdn.net/tototuzuoquan ...
-
asp.net mvc 三层加EF 登录注册 增删改查
首先打开vs软件新建项目创建web中的mvc项目再右击解决方案创建类库项目分别创建DAL层和BLL层再把DAL层和BLL层的类重命名在mvc项目中的Models文件夹创建model类在DAL创建ADO ...
-
popup的简单应用举例(具体在增删改查组件中用到)以及补充的知识点
一.首先说一下自执行函数 1. 立即执行函数是什么?也就是匿名函数 立即执行函数就是 声明一个匿名函数 马上调用这个匿名函数 2.popup的举例 点击,弹出一个新的窗口.保存完事,页面不刷新数据就返 ...
-
JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(三):两个Viewmodel搞定增删改查
前言:之前博主分享过knockoutJS和BootstrapTable的一些基础用法,都是写基础应用,根本谈不上封装,仅仅是避免了html控件的取值和赋值,远远没有将MVVM的精妙展现出来.最近项目打 ...
-
JS组件系列——又一款MVVM组件:Vue(一:30分钟搞定前端增删改查)
前言:关于Vue框架,好几个月之前就听说过,了解一项新技术之后,总是处于观望状态,一直在犹豫要不要系统学习下.正好最近有点空,就去官网了解了下,看上去还不错的一个组件,就抽空研究了下.最近园子里vue ...
随机推荐
-
SQL Server 游标运用:鼠标轨迹字符串分割
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 游标模板(Cursor Template) 鼠标轨迹字符串分割SQL脚本实现(SQL Code ...
-
C#Matlab混合编程类 初始化问题解决方法
************** 异常文本 ************** System.TypeInitializationException: “myPlus.matClass”的类型初始值设定项引发异 ...
-
Android中static和final用法小结
Java关键字static.final使用小结 static 1. static变量 按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量:另一种是 ...
-
Latex使用
tex是一种文本格式化程序语言,通过使用各种命令,对文本进行排版定义,最后通过编译,生成美观的排版完毕的文档. 同html.css的组合很想,定义元素以及元素的显示属性,按照编写好的文本格式化内容,在 ...
-
E: Some packages could not be authenticated
问题: 在Ubuntu上,安装软件时出现了“E: Some packages could not be authenticated”错误. 原因: 表示系统无法验证这个软件包 ...
-
[bzoj3953] [WF2013]Self-Assembly
将正方形视为连接字符间的边.比方说正方形上存在A+,B-,就从A-往B+连边,表示字符可以通过这个正方形进行变换. 如果能构成环的话就可以无穷大了...判环随便写个拓扑什么的... #include& ...
-
滴水穿石-01JAVA和C#的区别
排名不分先后,想到哪写到哪 1:数组的定义格式不同 java定义: 方式1: ] ; 方式2: ] ; C#中只有方式1 java有两种,C#只有一种 2:继承的实现关键字不同,同时java中实现接口 ...
-
牛客练习赛39D
n,m<=5e4; 首先操作2用并查集就行了.题解说的好啊! 考虑操作一,连的两个点如果同色,直接合并,然后这个颜色的联通块-1,然后合并bitset,就是或一下.bitset维护的是相连的异色 ...
-
redis 频率限制
方式1: $redis = new Redis(); //以自然时间控制 一自然分钟内超过100次进行限制, 屏蔽多久的时间必须为计数key时间的倍数 $key = 'xxxx'.date('Y-m- ...
-
[django]主次表如何取出对方数据[主表obj.子表__set()]
[sql]mysql管理手头手册,多对多sql逻辑 国家--城市例子 class Country(models.Model): name = models.CharField(max_length=3 ...