APS.NET MVC + EF (14)---项目框架搭建
一:框架搭建
1:先创建Model.
2:创建数据访问接口层。IUserInfoDal
在该接口中定义了常见的方法CURD以及分页方法。
public interface IUserInfoDal
{
IQueryable<UserInfo> LoadEntities(System.Linq.Expressions.Expression<Func<UserInfo, bool>> whereLambda);
IQueryable<UserInfo> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, System.Linq.Expressions.Expression<Func<UserInfo, bool>> whereLambda, System.Linq.Expressions.Expression<Func<UserInfo, s>> orderbyLambda, bool isAsc);
bool DeleteEntity(UserInfo entity);
bool EditEntity(UserInfo entity);
UserInfo AddEntity(UserInfo entity);
}
3:每个接口中都需要CURD以及分页方法的定义,而且这些方法的定义基本上是一致的,所以封装。封装到IBaseDal
public interface IBaseDal<T>where T:class,new()//注意该泛型的使用
{
IQueryable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda);
IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, System.Linq.Expressions.Expression<Func<T, bool>> whereLambda, System.Linq.Expressions.Expression<Func<T, s>> orderbyLambda, bool isAsc);
bool DeleteEntity(T entity);
bool EditEntity(T entity);
T AddEntity(T entity);
}
4:让IUserInfoDal继承IBaseDal
public interface IUserInfoDal:IBaseDal<UserInfo>
{
//定义自己特有的方法。
}
5:让具体的数据操作类UserInfoDal去实现IUserInfoDal接口中的方法。
public class UserInfoDal :IUserInfoDal
{
OAEntities Db = new OAEntities();
/// <summary>
/// 查询过滤
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public IQueryable<UserInfo> LoadEntities(System.Linq.Expressions.Expression<Func<UserInfo, bool>> whereLambda)
{
return Db.UserInfo.Where<UserInfo>(whereLambda);//
}
/// <summary>
/// 分页
/// </summary>
/// <typeparam name="s"></typeparam>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="totalCount"></param>
/// <param name="whereLambda"></param>
/// <param name="orderbyLambda"></param>
/// <param name="isAsc"></param>
/// <returns></returns>
public IQueryable<UserInfo> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, System.Linq.Expressions.Expression<Func<UserInfo, bool>> whereLambda, System.Linq.Expressions.Expression<Func<UserInfo, s>> orderbyLambda, bool isAsc)
{
var temp = Db.UserInfo.Where<UserInfo>(whereLambda);
totalCount = temp.Count();
if (isAsc)//升序
{
temp = temp.OrderBy<UserInfo, s>(orderbyLambda).Skip<UserInfo>((pageIndex - 1) * pageSize).Take<UserInfo>(pageSize);
}
else
{
temp = temp.OrderByDescending<UserInfo, s>(orderbyLambda).Skip<UserInfo>((pageIndex - 1) * pageSize).Take<UserInfo>(pageSize);
}
return temp;
}
/// <summary>
/// 删除
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public bool DeleteEntity(UserInfo entity)
{
Db.Entry<UserInfo>(entity).State = System.Data.EntityState.Deleted;
return Db.SaveChanges() > 0;
}
/// <summary>
/// 更新
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public bool EditEntity(UserInfo entity)
{
Db.Entry<UserInfo>(entity).State = System.Data.EntityState.Modified;
return Db.SaveChanges() > 0;
}
/// <summary>
/// 添加数据
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public UserInfo AddEntity(UserInfo entity)
{
Db.Set <UserInfo>().Add(entity);
Db.SaveChanges();
return entity;
}
}
6:由于每个数据操作类都要实现自己的接口(每一个接口都继承了IBaseDal),所以每个数据操作类中都要重复实现CURD以及分页的方法,所以把具体的实现封装到了BaseDal中。
public class BaseDal<T>where T:class,new()
{
OAEntities Db = new OAEntities();
/// <summary>
/// 查询过滤
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public IQueryable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda)
{
return Db.Set <T>().Where<T>(whereLambda);//
}
/// <summary>
/// 分页
/// </summary>
/// <typeparam name="s"></typeparam>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="totalCount"></param>
/// <param name="whereLambda"></param>
/// <param name="orderbyLambda"></param>
/// <param name="isAsc"></param>
/// <returns></returns>
public IQueryable<T> LoadPageEntities<s>(int pageIndex, int pageSize, out int totalCount, System.Linq.Expressions.Expression<Func<T, bool>> whereLambda, System.Linq.Expressions.Expression<Func<T, s>> orderbyLambda, bool isAsc)
{
var temp = Db.Set<T>().Where<T>(whereLambda);
totalCount = temp.Count();
if (isAsc)//升序
{
temp = temp.OrderBy<T, s>(orderbyLambda).Skip<T>((pageIndex - 1) * pageSize).Take<T>(pageSize);
}
else
{
temp = temp.OrderByDescending<T, s>(orderbyLambda).Skip<T>((pageIndex - 1) * pageSize).Take<T>(pageSize);
}
return temp;
}
/// <summary>
/// 删除
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public bool DeleteEntity(T entity)
{
Db.Entry<T>(entity).State = System.Data.EntityState.Deleted;
return Db.SaveChanges() > 0;
}
/// <summary>
/// 更新
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public bool EditEntity(T entity)
{
Db.Entry<T>(entity).State = System.Data.EntityState.Modified;
return Db.SaveChanges() > 0;
}
/// <summary>
/// 添加数据
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public T AddEntity(T entity)
{
Db.Set <T>().Add(entity);
Db.SaveChanges();
return entity;
}
7:让UserInfoDal继承BaseDal.
public class UserInfoDal : BaseDal<UserInfo>,IUserInfoDal
{
}
8:创建DBSession(数据会话层:就是一个工厂类,负责完成所有数据操作类实例的创建,然后业务层通过数据会话层来获取要操作数据类的实例。所以数据会话层将业务层与数据层解耦。
/// 在数据会话层中提供一个方法:完成所有数据的保存。)
作用:封装了数据层所有实例的创建,将BLL和DAL进行解耦,提供对数据操的统一访问点。提供一个方法,完成所有数据的保存。
private IUserInfoDal _UserInfoDal;
public IUserInfoDal UserInfoDal
{
get {
if (_UserInfoDal == null)
{
_UserInfoDal = new UserInfoDal();
}
return _UserInfoDal;
}
set
{
_UserInfoDal = value;
}
}
9: /// <summary>
/// 一个业务中经常涉及到对多张操作,我们希望链接一次数据库,完成对张表数据的操作。提高性能。 工作单元模式。
/// </summary>
/// <returns></returns>
public bool SaveChanges()
{
return Db.SaveChanges() > 0;
}
10:将数据层中的所有的保存数据的SaveChanges注释掉。
11:在数据层中用到了EF的实例,数据会话层中也用到了,所以在一个请求中只能创建一个EF实例(线程内唯一对象)
/// <summary>
/// 负责创建EF数据操作上下文实例,必须保证线程内唯一.
/// </summary>
public class DBContextFactory
{
public static DbContext CreateDbContext()
{
DbContext dbContext = (DbContext)CallContext.GetData("dbContext");
if (dbContext == null)
{
dbContext = new OAEntities();
CallContext.SetData("dbContext", dbContext);
}
return dbContext;
}
}
12:在DBSession和BaseDal中调用上面的方法(CreateDbContext)完成EF实例的创建。
DBSession获取EF实例
public DbContext Db
{
get
{
return DBContextFactory.CreateDbContext();
}
}
BaseDal中获取EF的实例
DbContext Db = DAL.DBContextFactory.CreateDbContext();
13:抽象抽象工厂封装数据操作类实例创建,然后DBSession调用抽象工厂。
在web.config 中配置数据层程序集的相关信息。
/// <summary>
/// 通过反射的形式创建类的实例
/// </summary>
public class AbstractFactory
{
private static readonly string AssemblyPath = ConfigurationManager.AppSettings["AssemblyPath"];
private static readonly string NameSpace = ConfigurationManager.AppSettings["NameSpace"];
public static IUserInfoDal CreateUserInfoDal()
{
string fullClassName = NameSpace + ".UserInfoDal";
return CreateInstance(fullClassName) as IUserInfoDal;
}
private static object CreateInstance(string className)
{
var assembly= Assembly.Load(AssemblyPath);
return assembly.CreateInstance(className);
}
}
然后修改DBSession
private IUserInfoDal _UserInfoDal;
public IUserInfoDal UserInfoDal
{
get {
if (_UserInfoDal == null)
{
//_UserInfoDal = new UserInfoDal();
_UserInfoDal = AbstractFactory.CreateUserInfoDal();//通过抽象工厂封装了类的实例的创建
}
return _UserInfoDal;
}
set
{
_UserInfoDal = value;
}
}
14:定义DBSession的接口
/// <summary>
/// 业务层调用的是数据会话层的接口。
/// </summary>
public interface IDBSession
{
DbContext Db { get; }
IUserInfoDal UserInfoDal { get; set; }
bool SaveChanges();
}
然后让DBSession实现该接口。
15:定义具体的业务基类
//在业务基类中完成DBSession的调用,然后将业务层中公共的方法定义在基类中,但是这些方法不知道通过DBSession来获取哪个数据操作类的实例。所以将该业务基类定义成抽象类,加上一个抽象方法,加上一个IBaseDal属性,并且让基类的构造方法调用抽象方法目的是在表现层new具体的业务子类,父类的构造方法被调用,这些执行抽象方法,但是执行的的是子类中具体的实现。业务子类知道通过DBSession获取哪个数据操作类的实例。
public abstract class BaseService<T> where T:class,new()
{
public IDBSession CurrentDBSession
{
get
{
return new DBSession();//暂时
}
}
public IDAL.IBaseDal<T> CurrentDal { get; set; }
public abstract void SetCurrentDal();
public BaseService()
{
SetCurrentDal();//子类一定要实现抽象方法。
}
public IQueryable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda)
{
return CurrentDal.LoadEntities(whereLambda);
}
}
16:定义业务层的接口。
17:保证业务层的DbSession线程内唯一
17:将数据库链接字符串拷贝到web.config文件中。
APS.NET MVC + EF (14)---项目框架搭建的更多相关文章
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(14)-主框架搭建
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(14)-主框架搭建 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 (2 ...
- .Net Core3.0 WebApi 项目框架搭建 五: 轻量型ORM+异步泛型仓储
.Net Core3.0 WebApi 项目框架搭建:目录 SqlSugar介绍 SqlSugar是国人开发者开发的一款基于.NET的ORM框架,是可以运行在.NET 4.+ & .NET C ...
- .Net Core3.0 WebApi 项目框架搭建 五:仓储模式
.Net Core3.0 WebApi 项目框架搭建:目录 理论介绍 仓储(Respository)是存在于工作单元和数据库之间单独分离出来的一层,是对数据访问的封装.其优点: 1)业务层不需要知道它 ...
- ssm项目框架搭建(增删改查案例实现)——(SpringMVC+Spring+mybatis项目整合)
Spring 常用注解 内容 一.基本概念 1. Spring 2. SpringMVC 3. MyBatis 二.开发环境搭建 1. 创建 maven 项目 2. SSM整合 2.1 项目结构图 2 ...
- Angular企业级开发(5)-项目框架搭建
1.AngularJS Seed项目目录结构 AngularJS官方网站提供了一个angular-phonecat项目,另外一个就是Angular-Seed项目.所以大多数团队会基于Angular-S ...
- (三) Angular2项目框架搭建心得
前言: 在哪看到过angular程序员被React程序员鄙视,略显尴尬,确实Angular挺值得被调侃的,在1.*版本存在的几个性能问题,性能优化的"潜规则"贼多,以及从1.*到2 ...
- 权限管理系统之项目框架搭建并集成日志、mybatis和分页
前一篇博客中使用LayUI实现了列表页面和编辑页面的显示交互,但列表页面table渲染的数据是固定数据,本篇博客主要是将固定数据变成数据库数据. 一.项目框架 首先要解决的是项目框架问题,搭建什么样的 ...
- go语言实战教程:实战项目资源导入和项目框架搭建
从本节内容开始,我们将利用我们所学习的Iris框架的相关知识,进行实战项目开发. 实战项目框架搭建 我们的实战项目是使用Iris框架开发一个关于本地服务平台的后台管理平台.平台中可以管理用户.商品.商 ...
- .Net Core3.0 WebApi 项目框架搭建:目录
一.目录 .Net Core3.0 WebApi 项目框架搭建 一:实现简单的Resful Api .Net Core3.0 WebApi 项目框架搭建 二:API 文档神器 Swagger .Net ...
随机推荐
- openstack Train版 “nova-status upgrade check”报错:Forbidden: Forbidden (HTTP 403)
部署openstack train版,在部署完nova项目时,进行检查,执行 nova-status upgrade check 返回报错信息如下: [root@controller ~]# nova ...
- 201871010104-陈园园 《面向对象程序设计(java)》第十二周学习总结
201871010104-陈园园 <面向对象程序设计(java)>第十二周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...
- 201871010104-陈园园 《面向对象程序设计(java)》第十一周学习总结
201871010104-陈园园 <面向对象程序设计(java)>第十一周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...
- 201871010134-周英杰《面向对象程序设计(java)》第十四周学习总结
项目 内容 这个作业属于哪个课程 <https://home.cnblogs.com/u/nwnu-daizh/> 这个作业的要求在哪里 <https://www.cnblogs.c ...
- uiautomator 调试例子
package com.bing.cn; import com.android.uiautomator.testrunner.UiAutomatorTestCase; public class Dem ...
- Lambda 表达式应用 权限管理_用户的角色修改
Lambda 表达式应用 权限管理_用户的角色修改 需求 前台发送用户新的角色列表,后台查询出用户原有的角色列表. 1.获取出需增加的角色列表 => 在新角色列表中,但是不在原角色列表中的角色 ...
- InfoQ一波文章:AdaSearch/JAX/TF_Serving/leon.bottou.org/Neural_ODE/NeurIPS_2018最佳论文
和 Nested Partition 有相通之处? 伯克利提出 AdaSearch:一种用于自适应搜索的逐步消除方法 在机器学习领域的诸多任务当中,我们通常希望能够立足预先给定的固定数据集找出问题的答 ...
- 启动hadoop后jps没有namenode,并且启动报错9000
启动hadoop报错: 解决方法: 我发现没有9000端口被占用,也不知道9000到哪去了,但是也没有NameNode,于是,直接把NameNode格式化了,再重启HDFS即可. 格式化命令:
- 第一章 了解Web及网络基础
第一章 了解Web及网络基础 Web建立基础.HTTP如何诞生发展 1.使用HTTP协议访问Web 在浏览器地址栏中输入URL之后过程: 1)DNS 解析:浏览器查询 DNS,获取域名对应的 IP 地 ...
- [LeetCode] 235. Lowest Common Ancestor of a Binary Search Tree 二叉搜索树的最小共同父节点
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...