OA项目CRUD和单元测试
Posted 石
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OA项目CRUD和单元测试相关的知识,希望对你有一定的参考价值。
使用ModeFirst方法生成数据库,EntityFramework5.0。
一:Model层的模型:(根据模型生成数据库)
二:Dal层的UserInfo代码:
namespace SunOA.EFDAL { public class UserInfoDal { //crud DataModelContainer db = new DataModelContainer(); public UserInfo GetUserInfoById(int id) { return db.UserInfo.Find(id); } public List<UserInfo> GetAllUserInfo(int id) { return db.UserInfo.ToList(); } /// <summary> /// 用到的时候在去查询 IQueryable 转换成 Queryable 集合 取代上面的两个查询方法 /// </summary> /// <param name="?"></param> /// <returns></returns> public IQueryable<UserInfo> GetUsers(Expression<Func<UserInfo,bool>> whereLambda) { return db.UserInfo.Where(whereLambda).AsQueryable(); } /// <summary> /// 增加 /// </summary> /// <param name="userInfo"></param> /// <returns></returns> public UserInfo Add(UserInfo userInfo) { db.UserInfo.Add(userInfo); db.SaveChanges(); return userInfo; } /// <summary> /// 修改 /// </summary> /// <param name="userInfo"></param> /// <returns></returns> public bool Update(UserInfo userInfo) { //db.Entry(userInfo).State = EntityState.Unchanged; //上面的代码等价于下面的这个代码 // db.UserInfo.Attach(userInfo); //整体修改 db.Entry(userInfo).State = EntityState.Modified; //修改方法中的一个属性 return db.SaveChanges()>0; } /// <summary> /// 删除 /// </summary> /// <param name="userInfo"></param> /// <returns></returns> public bool Delete(UserInfo userInfo) { db.Entry(userInfo).State = EntityState.Deleted; return db.SaveChanges() > 0; } } }
分页的代码:
/// <summary> /// 分页的语句 /// </summary> /// <param name="pageSize"></param> /// <param name="pageIndex"></param> /// <param name="total"></param> /// <param name="whereLambda"></param> /// <returns></returns> public IQueryable<UserInfo> GetPageUsers<S>(int pageSize, int pageIndex, out int total, Expression<Func<UserInfo, bool>> whereLambda, Expression<Func<UserInfo,S>> orderByLambda, bool isAsc) { total = db.UserInfo.Where(whereLambda).Count(); if (isAsc) { var temp = db.UserInfo.Where(whereLambda).OrderBy<UserInfo, S>(orderByLambda).Skip(pageSize*(pageIndex - 1)) .Take(pageSize).AsQueryable(); return temp; } else { var temp = db.UserInfo.Where(whereLambda).OrderByDescending<UserInfo, S>(orderByLambda).Skip(pageSize*(pageIndex - 1)) .Take(pageSize).AsQueryable(); return temp; } }
单元测试:(引入Model和Dal)
namespace SunOA.UnitTest { [TestClass, System.Runtime.InteropServices.GuidAttribute("7651815F-CEE5-4E48-9CCF-4032C79CA9B8")] public class UserInfoDalTest { [TestMethod] public void GetUsers() { //测试 获取数据的方法 UserInfoDal dal = new UserInfoDal(); //单元测试必须自己处理数据,不能依赖第三方数据 如果依赖数据那么先自己创建数据,用完之后再清除数据 for (int i = 0; i < 10; i++) { dal.Add(new UserInfo() { UName=i+"sun" }); } IQueryable<UserInfo> temp= dal.GetUsers(u => u.UName.Contains("su")); //断言 Assert.AreEqual(true, temp.Count() >= 10); } } }
执行成功数据库会插入数据:
在添加一个Model类,又得有对应的CRUD方法,所以封装一个BaseDal的公用Dal。
/// <summary> /// 职责:封装所有Dal的公共CRUD /// </summary> public class BaseDal<T> where T:class,new() { DataModelContainer db = new DataModelContainer(); /// <summary> /// 用到的时候在去查询 IQueryable 转换成 Queryable 集合 取代上面的方法 /// </summary> /// <param name="?"></param> /// <returns></returns> public IQueryable<T> GetEntites(Expression<Func<T, bool>> whereLambda) { return db.Set<T>().Where(whereLambda).AsQueryable(); } /// <summary> /// 分页的语句 /// </summary> /// <param name="pageSize"></param> /// <param name="pageIndex"></param> /// <param name="total"></param> /// <param name="whereLambda"></param> /// <returns></returns> public IQueryable<T> GetPageEntites<S>(int pageSize, int pageIndex, out int total, Expression<Func<T, bool>> whereLambda, Expression<Func<T, S>> orderByLambda, bool isAsc) { total = db.Set<T>().Where(whereLambda).Count(); if (isAsc) { var temp = db.Set<T>().Where(whereLambda).OrderBy<T, S>(orderByLambda).Skip(pageSize * (pageIndex - 1)) .Take(pageSize).AsQueryable(); return temp; } else { var temp = db.Set<T>().Where(whereLambda).OrderByDescending<T, S>(orderByLambda).Skip(pageSize * (pageIndex - 1)) .Take(pageSize).AsQueryable(); return temp; } } /// <summary> /// 增加 /// </summary> /// <param name="T"></param> /// <returns></returns> public T Add(T entity) { db.Set<T>().Add(entity); db.SaveChanges(); return entity; } /// <summary> /// 修改 /// </summary> /// <param name="T"></param> /// <returns></returns> public bool Update(T entity) { //db.Entry(T).State = EntityState.Unchanged; //上面的代码等价于下面的这个代码 // db.T.Attach(T); //整体修改 db.Entry(entity).State = EntityState.Modified; //修改方法中的一个属性 return db.SaveChanges() > 0; } /// <summary> /// 删除 /// </summary> /// <param name="entity"></param> /// <returns></returns> public bool Delete(T entity) { db.Entry(entity).State = EntityState.Deleted; return db.SaveChanges() > 0; } }
UserInfoDal:和 OrderInfoDal继承BaseDal
public class OrderInfoDal:BaseDal<OrderInfo> { } public class UserInfoDal:BaseDal<UserInfo> { }
BLL层 UserInfoService:
namespace SunOA.BLL
{
//模块内高内聚,低耦合
//变化点:1.跨数据库
//先用接口隔离具体的实现
public class UserInfoService
{
//不管new哪个Dal 下面都没有任何变化
IUserInfoDal userInfoDal=new UserInfoDal(); NhUserInfoDal();
public UserInfo Add(UserInfo userInfo)
{
return userInfoDal.Add(userInfo);
}
}
}
OrderInfoService:(如果多的话都得修改)
namespace SunOA.BLL
{
public class OrderInfoService
{
public OrderInfo Add(OrderInfo orderInfo)
{
IUserInfoDal userInfoDal = new UserInfoDal(); NhUserInfoDal(); 这是变化点
return orderInfo;
}
}
}
层与层依赖于接口IBaseDal:
public interface IBaseDal<T> where T:class,new() { /// <summary> /// 用到的时候在去查询 IQueryable 转换成 Queryable 集合 取代上面的方法 /// </summary> /// <param name="?"></param> /// <returns></returns> IQueryable<T> GetEntites(Expression<Func<T, bool>> whereLambda); /// <summary> /// 分页的语句 /// </summary> /// <param name="pageSize"></param> /// <param name="pageIndex"></param> /// <param name="total"></param> /// <param name="whereLambda"></param> /// <returns></returns> IQueryable<T> GetPageEntites<S>(int pageSize, int pageIndex, out int total, Expression<Func<T, bool>> whereLambda, Expression<Func<T, S>> orderByLambda, bool isAsc); /// <summary> /// 增加 /// </summary> /// <param name="T"></param> /// <returns></returns> T Add(T entity); /// <summary> /// 修改 /// </summary> /// <param name="T"></param> /// <returns></returns> bool Update(T entity); /// <summary> /// 删除 /// </summary> /// <param name="entity"></param> /// <returns></returns> bool Delete(T entity); }
所有类的接口继承于IBaseDal:
public interface IOrderInfoDal:IBaseDal<OrderInfo> { } public interface IUserInfoDal:IBaseDal<UserInfo> { }
UserInfoDal和OrderInfoDal分别实现IUserInfoDal和IOrderInfoDal接口。
public class OrderInfoDal:BaseDal<OrderInfo>,IOrderInfoDal public class UserInfoDal:BaseDal<UserInfo>,IUserInfoDal
写一个静态工厂:
public class StaticDalFactory { public static IUserInfoDal GetUserInfoDal() { return new UserInfoDal(); } }
OrderInfoService和UserInfoService:
public class OrderInfoService { public OrderInfo Add(OrderInfo orderInfo) { IUserInfoDal userInfoDal = StaticDalFactory.GetUserInfoDal(); return orderInfo; } }
//静态工厂 private IUserInfoDal UserInfoDal = StaticDalFactory.GetUserInfoDal(); public UserInfo Add(UserInfo userInfo) { return userInfoDal.Add(userInfo); }
public static IOrderInfoDal GetOrderInfoDal() { return new OrderInfoDal(); }
抽象工厂的实现:
引用命名空间:
using System.Reflection;
WebConfig中的配置:
<appSettings> <!--抽象工厂创建数据库访问层实例所在的 程序集的名称--> <add key="DalAssemblyName" value="SunOA.EFDAL" /> </appSettings>
静态工厂:
public class StaticDalFactory { public static string assemblyName = System.Configuration.ConfigurationManager.AppSettings["DalAssemblyName"]; public static IUserInfoDal GetUserInfoDal() { // return new UserInfoDal(); //把new去掉 改一个配置创建实体就发生变化,不需要改代码 return Assembly.Load(assemblyName).CreateInstance(assemblyName + ".UserInfoDal") as IUserInfoDal; } public static IOrderInfoDal GetOrderInfoDal() { return Assembly.Load(assemblyName).CreateInstance(assemblyName + ".OrderInfoDal") as IOrderInfoDal; } }
Service层的代码:
private IUserInfoDal UserInfoDal = StaticDalFactory.GetUserInfoDal(); public UserInfo Add(UserInfo userInfo) { return UserInfoDal .Add(userInfo); }
IBaseServie的代码:
public interface IBaseService<T> where T :class,new() { IQueryable<T> GetEntities(Expression<Func<T, bool>> whereLambda); IQueryable<T> GetPageEntities<S>(int pageSize, int pageIndex, out int total, Expression<Func<T, bool>> whereLambda, Expression<Func<T, S>> orderByLambda, bool isAsc); T Add(T entity); bool Update(T entity); bool Delete(T entity); }
BaseService的代码:
namespace SunOA.BLL { /// <summary> /// 父类要逼迫自己给父类的一个属性赋值 赋值的操作必须在父类的方法调用之前执行 /// </summary> /// <typeparam name="T"></typeparam> public abstract class BaseService<T> where T:class ,new() { public IBaseDal<T> CurrentDal { get; set; } /// <summary> /// DbSession 做成属性 /// </summary> public IDbSession DbSession { get { return DbSessionFactory.GetCurrentDbSession(); } } /// <summary> /// 基类的构造函数 /// </summary> public BaseService() { //调用了抽象方法 SetCurrentDal(); } //抽象方法:要求子类必须实现抽象方法,对此方法进行重写 public abstract void SetCurrentDal(); /// <summary> /// 用到的时候在去查询 IQueryable 转换成 Queryable 集合 取代上面的方法 /// </summary> /// <param name="?"></param> /// <returns></returns> public IQueryable<T> GetEntites(Expression<Func<T, bool>> whereLambda) { return CurrentDal.GetEntites(whereLambda); } /// <summary> /// 分页的语句 /// </summary> /// <param name="pageSize"></param> /// <param name="pageIndex"></param> /// <param name="total"></param> /// <param name="whereLambda"></param> /// <returns></returns> public IQueryable<T> GetPageEntites<S>(int pageSize, int pageIndex, out int total, Expression<Func<T, bool>> whereLambda, Expression<Func<T, S>> orderByLambda, bool isAsc) { return CurrentDal.GetPageEntites(pageSize, pageIndex, out total, whereLambda, orderByLambda, isAsc); } /// <summary> /// 增加 /// </summary> /// <param name="T"></param> /// <returns></returns> public T Add(T entity) { CurrentDal.Add(entity); DbSession.SaveChanges(); return entity; } /// <summary> /// 修改 /// </summary> /// <param name="T"></param> /// <returns></returns> public bool Update(T entity) { CurrentDal.Update(entity); return DbSession.SaveChanges() > 0; } /// <summary> /// 删除 /// </summary> /// <param name="entity"></param> /// <returns></returns> public bool Delete(T entity) { CurrentDal.Delete(entity); return DbSession.SaveChanges() > 0; } } }
IOrderInfoService的代码:
public interface IUserInfoService:IBaseService<UserInfo> { }
OrderInfoService的代码:
public class OrderInfoService:BaseService<OrderInfo> { /// <summary> /// 赋值给当前的Dal /// </summary> public override void SetCurrentDal() { CurrentDal = DbSession.OrderInfoDal; } }
控制器中的代码:
public class UserInfoController : Controller { // // GET: /UserInfo/ UserInfoService userInfoService = new UserInfoService(); public ActionResult Index() { ViewData.Model = userInfoService.GetEntites(u => true); return View(); } public ActionResult Create() { return View(); } [HttpPost] public ActionResult Create(UserInfo userInfo) { if (ModelState.IsValid) { userInfoService.Add(userInfo); } return RedirectToAction("Index"); } }
前台代码自动生成。最后进行展示。
以上是关于OA项目CRUD和单元测试的主要内容,如果未能解决你的问题,请参考以下文章
MyBatisMyBatis CRUD操作单元测试的使用${} 与 #{} 的区别