EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

1:项目结构

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

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

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

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

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

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

BLL层依赖 Common层,Model层

Common依赖 Model层

Repository依赖 Model和Common层

BLL依赖 Model,Common,Repository层

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

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查  最后的生成顺序是  EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

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

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

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文件

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

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 类

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

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 父类出来

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

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  用户表业务逻辑操作类 只需要继承一下这业务基类就可以了

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

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

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

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

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

6. 我们在UI层 进行调用

EF5+MVC4系列(6) 简单三层的搭配(泛型) 实现 增删改查

上一篇:C功底挑战Java菜鸟入门概念干货(一)


下一篇:模拟赛1030d1