首先分享一点自己最近的感悟:讨厌你的人总可以找到理由去讨厌你

正文开始

如果您是初次阅读这个系列,请先去《Index & Writing Plan》查找并阅读“架构设计系列”的前两篇文章,顺序阅读会使您有更好的阅读体验

强烈推荐配合源代码阅读本文:点击此处下载(可以直接运行,会在本地自动生成数据库)

已经写完了Factory的实现。在Factory中,我们使用了预编译指令来实现了Model的切换:

#define A
#if B
using Model.B;
using DBaccess.B;
#endif
#if A
using Model.A;
using DBaccess.A;
#endif

切换Model,只需将#define A 修改为 #define B,非常方便(尽管要重新编译,还是让我有点不爽)

但是出现预编译指令的地方不宜过多——事实上,已经有一处要改就已经让我不爽了

所以,在DM层(数据操作层)与Service层(业务逻辑层)中,我们不能出现任何具体的Model的类名。

在本例中,就是DM和Service中不能出现类名:Teacher、Contact

因为每个出现了类Teacher和类Contact的地方,我们都要加上前文提到的预编译指令。而在实际项目中,这样做会导致切换Model要修改的地方非常多,可能会导致不可预期的错误

那么,DM层主要是用泛型来解决问题,代码如下:

public class DMbase{protected DbContext db;public DMbase(DbContext db){this.db = db;}/// <summary>/// select one/// </summary>/// <typeparam name="T"></typeparam>/// <param name="entity">这里的entity并无实际作用,只是用于编译器推敲类型</param>/// <param name="predicate">λ表达式</param>/// <returns>返回第一条匹配的记录,若无记录返回null</returns>public virtual T FindOne<T>(T entity, Func<T, bool> expression) where T : class, new(){return this.db.Set<T>().FirstOrDefault(expression);}/// <summary>/// select all/// </summary>/// <typeparam name="T"></typeparam>/// <param name="entity">这里的entity并无实际作用,只是用于编译器推敲类型</param>public virtual IQueryable<T> FindAll<T>(T entity) where T : class, new(){return this.db.Set<T>();}public virtual void Insert<T>(params T[] entities)where T : class, new(){if (entities != null && entities.Length > 0){var set = this.db.Set<T>();foreach (var item in entities){set.Add(item);}}}public virtual void Delete<T>(params T[] entities)where T : class, new(){if (entities != null && entities.Length > 0){var set = this.db.Set<T>();foreach (var item in entities){set.Remove(item);}}}/// <summary>/// 提交事务/// </summary>public void Commit(){this.db.SaveChanges();}}

我的注释也说明了,其实FindOne方法和FindAll方法其实是不需要参数的,但是为了编译器推敲类型,传入了一个entity参数

在此要感谢下xanthodont同学,这个DM是在你的版本上改的,封装得很不错

写完DM层,接下来就是重头戏,Service层

下面的代码示范了如何取得所有的Teacher,并将Teacher与Contact对应起来

        public object FindAllTeacher(){//取得一个Contextvar context = ContextFactory.GetContext();//从Factory中取得Teacher和Contact//这里必须要用varvar a = ModelFactory.GetTeacher();var b = ModelFactory.GetContact();var aList = ModelListFactory.GetTeacherList();DMbase dm = new DMbase(context);//用之前取得的Teacher与Contact传入DM层,方便编译器推敲类型var contact = dm.FindAll(b);var teacher = dm.FindAll(a);//业务逻辑,将Teacher与Contact关联起来var result = teacher.Join(contact, o => o.ID, r => r.TeacherID, (o, r) => new { tt = o, aa = r });result = result.OrderByDescending(o => o.aa.Email);//处理数据foreach (var item in result){a = item.tt;a.Contact = item.aa;aList.Add(a);}return aList;}

注意,这里我使用了Object作为返回类型,因为我其实不知道返回值是IList<Model.A.Teacher> 还是IList<Model.B.Teacher>,好在这里只需要一次拆装箱,无伤大雅

再来演示下如何插入:

        public bool AddTeacher<T, T1>(T teacher, T1 contact)where T : class,new()where T1 : class,new(){try{var context = ContextFactory.GetContext();DMbase dm = new DMbase(context);dm.Insert(teacher);dm.Insert(contact);dm.Commit();return true;}catch{return false;}}

只有执行了dm.Commit(),两个Insert才会提交到数据库,保证了事务的一致性

就此搁笔

PS:昨天是博主生日,又老了一岁;有缘读到这里的园友,就别吝啬自己的祝福了吧 :)

转载于:https://www.cnblogs.com/CrazyJinn/archive/2012/10/30/2745969.html

一步一步搭架子(DM层与Service层)相关推荐

  1. Dao层和Service层的区别

    举个栗子: 传统访问数据库的方法非常面向过程,分为以下几步 – 实例化connection – 实例化statement – 通过statement的参数sql语句访问数据库,返回数据进行处理 imp ...

  2. java dao层 service层_Java中DAO层、Service层和Controller层的区别

    DAO层: DAO层叫数据访问层,全称为data access object,属于一种比较底层,比较基础的操作,具体到对于某个表的增删改查,也就是说某个DAO一定是和数据库的某一张表一一对应的,其中封 ...

  3. Java中dao层、service层、controller层、entity层和view层的概述

    目录 DAO层:(持久层)主要与数据库进行交互 Service层:(业务层 )控制业务 Controler层:(控制层 )控制业务逻辑 Entity层: (实体层 )数据库在项目中的类 View层: ...

  4. DAO层、ENTITY层、SERVICE层、CONTROLLER层

    dao层.entity层.service层.controller层 2018年08月09日 11:02:31 一江春华终散去 阅读数:3074 版权声明:本文为博主原创文章,未经博主允许不得转载. h ...

  5. SpringBoot框架中的DAO(mapper)层、Entity层、Service层、Controller层

    Entity层:实体层 数据库在项目中的类 Entity层是实体层,也就是所谓的model,也称为pojo层,是数据库在项目中的类,该文件包含实体类的属性和对应属性的set.get方法: DAO层: ...

  6. OA系统二十四:请假审批五:【点击“审批”后的审批弹出框】的后台逻辑;(审批结果提交的Dao层和Service层逻辑)

    本篇博客的主要内容是:[请假审批内嵌页面],[审批弹出框]的点击"确认提交"后,后台的逻辑:主要是Dao层和Service层这些后台逻辑:  说明: (1)目前来看,为了实现某个功 ...

  7. SpringBoot框架分层(View层、Controller层、Service层、Mapper层、pojo层)

    SpringBoot框架一般分为View层.Controller层.Service层.Mapper层.pojo层. View层:视图层,根据接到的数据展示页面给用户 Controller层:响应用户需 ...

  8. pojo层、dao层、service层、controller层的作用

    pojo层(model) 实体层 数据库在项目中的类 model是模型的意思,与entity.domain.pojo类似,是存放实体的类. 类中定义了多个类属性,并与数据库表的字段保持一致,一张表对应 ...

  9. 三层架构编程、DAO层、Entity层、Service层、Controller层

    什么是三层架构编程: 本质上所有的项目(应用程序)都是需要和用户交互,然后产生数据,对数据进行处理,最后将数据存储到硬盘这么个过程 在编程中,可以将这个过程分一下层次,最初只分两层,用户层和数据层,但 ...

  10. SSM框架中各层的含义和联系(Pojos层、Dao层、Service层、Action层......)

    一.pojo层 即Plain Ordinary Java Object,也有人称其为model.domain.bean等,pojo层是对应的数据库表的实体类. 二.1.持久层:Dao层(Mapper) ...

最新文章

  1. 毕业设计:基于Springboot实现物流统计分析系统
  2. HDU-2102 A计划 dfs
  3. Typeface 字体样式
  4. Kali Linux 2016.2初体验
  5. Redis:20---常用功能之(发布与订阅)
  6. 美媒:小米新浪达成合作 采取行动对抗腾讯
  7. JUnit5 @AfterEach注解示例
  8. ES6-ES11新特性_ECMAScript_简单介绍---JavaScript_ECMAScript工作笔记001
  9. 如何用VS2015手撕白菜
  10. C语言 - 常见面试题整理
  11. pandas库与numpy库
  12. 我的2020年终回顾:人生,海海,破浪前行
  13. Debian9.5系统DNS服务器BIND软件配置说明
  14. 小学生计算机编程题,真题|小学组倒数第二道编程题,做不出来罚你点赞三遍!...
  15. 个人手机网站接入支付宝在线收款功能
  16. 对学习数据结构的建议
  17. 【将数组a中n个整数按相反顺序存放】
  18. 利用JS调用手机摄像头小功能源码
  19. hahaha终于注册了一个博客
  20. [转]Linux: 结束查看进程命令

热门文章

  1. IntelliJ IDEA注册码
  2. jmeter 正则表达式
  3. 【知识积累】随机数生成的几种方法
  4. php中的elseif和else if
  5. 小实验:用创建进程()打开计算器,然后关闭进程句柄。再用打开进程(进程ID),使用两次,得到两个进程句柄。实验目的:这两个进程句柄都能控制这个进程吗?通过该试验加深对句柄的理解!!...
  6. 关于sharepoint
  7. mysql-4.0.20 use on scounix 5.0.7 error :dynamic linker:..:could not open libgthreads.so help!!!!
  8. 使用ADO.NET直接连接Geodatabase
  9. 6.10 docker (二) 守护态运行
  10. python学习干货教程(5):#!/usr/bin/python