一:框架搭建

 
 

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)---项目框架搭建的更多相关文章

  1. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(14)-主框架搭建

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(14)-主框架搭建    ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2 ...

  2. .Net Core3.0 WebApi 项目框架搭建 五: 轻量型ORM+异步泛型仓储

    .Net Core3.0 WebApi 项目框架搭建:目录 SqlSugar介绍 SqlSugar是国人开发者开发的一款基于.NET的ORM框架,是可以运行在.NET 4.+ & .NET C ...

  3. .Net Core3.0 WebApi 项目框架搭建 五:仓储模式

    .Net Core3.0 WebApi 项目框架搭建:目录 理论介绍 仓储(Respository)是存在于工作单元和数据库之间单独分离出来的一层,是对数据访问的封装.其优点: 1)业务层不需要知道它 ...

  4. ssm项目框架搭建(增删改查案例实现)——(SpringMVC+Spring+mybatis项目整合)

    Spring 常用注解 内容 一.基本概念 1. Spring 2. SpringMVC 3. MyBatis 二.开发环境搭建 1. 创建 maven 项目 2. SSM整合 2.1 项目结构图 2 ...

  5. Angular企业级开发(5)-项目框架搭建

    1.AngularJS Seed项目目录结构 AngularJS官方网站提供了一个angular-phonecat项目,另外一个就是Angular-Seed项目.所以大多数团队会基于Angular-S ...

  6. (三) Angular2项目框架搭建心得

    前言: 在哪看到过angular程序员被React程序员鄙视,略显尴尬,确实Angular挺值得被调侃的,在1.*版本存在的几个性能问题,性能优化的"潜规则"贼多,以及从1.*到2 ...

  7. 权限管理系统之项目框架搭建并集成日志、mybatis和分页

    前一篇博客中使用LayUI实现了列表页面和编辑页面的显示交互,但列表页面table渲染的数据是固定数据,本篇博客主要是将固定数据变成数据库数据. 一.项目框架 首先要解决的是项目框架问题,搭建什么样的 ...

  8. go语言实战教程:实战项目资源导入和项目框架搭建

    从本节内容开始,我们将利用我们所学习的Iris框架的相关知识,进行实战项目开发. 实战项目框架搭建 我们的实战项目是使用Iris框架开发一个关于本地服务平台的后台管理平台.平台中可以管理用户.商品.商 ...

  9. .Net Core3.0 WebApi 项目框架搭建:目录

    一.目录 .Net Core3.0 WebApi 项目框架搭建 一:实现简单的Resful Api .Net Core3.0 WebApi 项目框架搭建 二:API 文档神器 Swagger .Net ...

随机推荐

  1. 在表单中使用ajax,成功后跳转指定页面 出现Provisional headers are shown 解决办法

    问题回顾: 在表单里面,有个button按钮,在点击这个button的时候,我发送了ajax请求,然后请求成功的话,就使用window.location.href = xxx,跳转到其他页面 但是,一 ...

  2. windows及linux环境下修改pip的默认镜像源的方法

    1. 在windows环境下 临时修改 使用清华大学的源安装numpy包. pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple ...

  3. GIC , SPI , PPI (窝窝科技的文章题目改了下)【转】

    转自:https://www.cnblogs.com/tureno/articles/6403408.html 转载于:  http://www.wowotech.net/irq_subsystem/ ...

  4. 005-OpenStack-网络服务

    OpenStack-网络服务 [基于此文章的环境]点我快速打开文章 1.控制节点(controller) 1.1 创库授权 neutron mysql CREATE DATABASE neutron; ...

  5. IOI 2020 集训队作业胡扯

    首先安慰自己:做的没集训队快很正常-- 很正常-- 做不完也很正常-- 很正常-- 全都不会做也很正常-- 很正常-- 表格 试题一 完成情况 试题二 完成情况 试题三 完成情况 cf549E cf6 ...

  6. 登录-退出,在T分钟实现BC次用户登录退出,单次登录-退出%90用户时间t,需要的并发用户(线程)

    聚合报告%90响应时间:%90用户响应时小于该值 2种理解方式: 一. 1s可完成的用户1/t: T分钟完成的用户T *(1/t); BC次用户需要的线程数Thread= BC/(T*(1/t)) = ...

  7. Provider和Consumer的搭建(六)

    创建三个Maven Project: dubbo-service:公共模块,包括服务接口(packaging:jar) dubbo-service-impl:服务提供方,提供服务接口的具体实现,需要依 ...

  8. JAVA还没死的原因

    尽管 TIOBE 指数显示,Java 是一门正在衰落的语言,但它仍然稳居榜首.从 2016 年到 2017 年间,这个数字可能会大幅下降,但最近下降速度有所放缓:在 2018 年 10 月到 2019 ...

  9. Xamarin.Forms移动开发系列3:项目剖析

    摘要 本文主要进行Xamarin.Forms应用程序剖析. 前言 本文介绍Xamarin.Forms应用程序剖析. 由于本系列重点研究对象为Xamarin.Forms,所以对Xamarin.Andro ...

  10. MySQL实战45讲学习笔记:第二十一讲

    一.引子 在上一篇文章中,我和你介绍了间隙锁和 next-key lock 的概念,但是并没有说明加锁规则.间隙锁的概念理解起来确实有点儿难,尤其在配合上行锁以后,很容易在判断是否会出现锁等待的问题上 ...