博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一步一步搭架子(DM层与Service层)
阅读量:6324 次
发布时间:2019-06-22

本文共 3761 字,大约阅读时间需要 12 分钟。

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

 

正文开始

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

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

 

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

#define A#if Busing Model.B;using DBaccess.B;#endif#if Ausing 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;        }        ///         /// select one        ///         /// 
/// 这里的entity并无实际作用,只是用于编译器推敲类型 /// λ表达式 ///
返回第一条匹配的记录,若无记录返回null
public virtual T FindOne
(T entity, Func
expression) where T : class, new() { return this.db.Set
().FirstOrDefault(expression); } ///
/// select all /// ///
///
这里的entity并无实际作用,只是用于编译器推敲类型 public virtual IQueryable
FindAll
(T entity) where T : class, new() { return this.db.Set
(); } public virtual void Insert
(params T[] entities) where T : class, new() { if (entities != null && entities.Length > 0) { var set = this.db.Set
(); foreach (var item in entities) { set.Add(item); } } } public virtual void Delete
(params T[] entities) where T : class, new() { if (entities != null && entities.Length > 0) { var set = this.db.Set
(); foreach (var item in entities) { set.Remove(item); } } } ///
/// 提交事务 /// public void Commit() { this.db.SaveChanges(); } }

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

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

 

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

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

public object FindAllTeacher()        {            //取得一个Context            var context = ContextFactory.GetContext();            //从Factory中取得Teacher和Contact            //这里必须要用var            var 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 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

你可能感兴趣的文章
centos 7.4 使用 pgxc_ctl 安装与使用
查看>>
【数据库】表分区
查看>>
img垂直水平居中与div
查看>>
订餐系统之同步美团商家订单
查看>>
CentOS 6.9通过RPM安装EPEL源(http://dl.fedoraproject.org)
查看>>
采集音频和摄像头视频并实时H264编码及AAC编码
查看>>
堆排序算法
查看>>
STM32的TAMPER-RTC管脚作为Tamper的使用[转]
查看>>
[记]一个逐步“优化”的范例程序
查看>>
2012-01-09_2
查看>>
数学 - 线性代数导论 - #5 矩阵变换之置换与转置
查看>>
java数据结构:队列
查看>>
使用.NET进行高效率互联网敏捷开发的思考和探索【一、概述】
查看>>
SSM练习——登录实现
查看>>
余光中_百度百科
查看>>
方法sessionjsp之监听器
查看>>
判断 网络是否通常,以及判断用户使用的网络类型,时2G\3G\还是wifi
查看>>
下一代 Hadoop YARN :相比于MRv1,YARN的优势
查看>>
阿里巴巴离职DBA 35岁总结的职业生涯
查看>>
LOT NUMBER / PO / RECEIPT NO Relation.
查看>>