一起谈.NET技术,浅谈C#中的延迟加载(2)——善用virtual

  之前的文章"浅谈C#中的延迟加载(1)——善用委托"中介绍了三层结构中在Model层对实体类的属性实现延迟加载的方法,该方法利用C#中的委托来实现,最后虽然延迟加载的目的得以实现,但是给客户端(例如UI层)暴露了不必要的属性(一个委托对象,我使用了泛型的Fun类来实现)。这篇文章介绍一种方法来隐藏这个属性,同时又可以达到延迟加载的目的,更重要的是这一切都是在之前的基础上来完成的,不需要改变原来使用到实体类的地方的代码。

  按照惯例,我们考虑一下想要我们的代码达到什么效果:首先在Model.Acticle(文章实体类)中的Category属性和原来一样,只在需要的时候通过调用委托来获取文章所属分类(Model.ArticleCategory类)。同时这个委托是不被客户端(例如UI层)代码看到的。。。设计模式中有一句话,大致的意思是通常在两个事物之间加上一个中间层,可以把事情变得简单,于是我们这样考虑,能不能加多一个中间层来实现呢?

  把Category属性定义为虚拟的(virtual),去掉委托,继承Model.Acticle类实现一个子类,把委托放到到这个子类里面来,由个子类里面去实现Category属性的get选择器,客户端访问的是一个用该子类做实例化的Model.Acticle类对象,这样一来客户端代码访问的依旧是Model.Acticle类,但是看不到用于实现延迟加载的委托却又能在Category属性中获取到需要的数据。呵呵,由于我是写文章的人,所以觉得这个思路很好理解,但是看文字的您可能感觉有点晕,下面用代码来说明应该就清楚了。

  首先我们修改Model.Acticle类,给他瘦身,瘦身结果如下:


c#代码
// 文章实体类
  public class Article
 {
 public int ArticleID { get; set; }
 public string Title { get; set; }
 public string Cotnent{ get; set; }
 public DateTime CreateTime { get; set; }
 public int CategoryID { get; set; }
 // 文章所属分类
  public virtual Model.ArticleCategory Category
 {
get;
}
 }

  对比上一篇文章,可以发现作为延迟加载用的委托不见了,另外就是Category的get选择器中不再有任何逻辑代码,并且该属性被声明为virtual了。

  下一步我们创建多一层出来。新建一个名为DModel的类库(注意:该层需要引用Model层,然后被Dal层引用)。接下来在DModel层也创建一个Article类,没错!用他来继承Model.Acticle类。Dmodel.Acticle长成下面这个样子:


c#代码
 namespace DModel{
 // 文章 
public class Article : Model.Article
 {
 // 所属分类
 protected Model.ArticleCategory _category;
 public override Model.ArticleCategory Category
 {
 get
 {
if (_category == null)
{
if (CategoryLazyLoader != null)
{
 _category = CategoryLazyLoader(CategoryID);
 }
else
 {
_category = null;
 }
 }
 return _category;
 }
 }
 // 文章分类延时加载器(委托)
 public Func<int, Model.ArticleCategory> CategoryLazyLoader { get; set; } }}

  是的,看到了么,委托跑这儿来了,并且他实现了Model.Acticle的Category属性的get选择器,里面的逻辑是不是也很熟悉呢。

  接着还有一个地方要做点小修改,就是Dal层中获取一个文章实体类的方法,也就是前一篇文章中写到的public Model.Article GetArticleById(int articleId)方法了,修改后如下:


c#代码
 // 根据文章ID获取文章实体类对象public Model.Article GetArticleById(int articleId){
 // 从数据库中取出数据,得到一个DateRow或者DateRader之类的东东然后初始化一个文章实体类对象
 DModel.Article article = ... // ...是代码 - -!
 // 创建文章分类数据访问对象
 Dal.ArticleCategory articleCategory = new Dal.ArticleCategory();
 // 指定延时加载委托
 article.CategoryLazyLoader = articleCategory.GetArticleCategoryById;
 // 返回文章对象
 return article;}

  请注意上面代码中这一句,DModel.Article article = ... // ...是代码 - -!,我们得到一个DModel.Article对象,最后以Model.Article的形式返回(C#中的装箱,是吧~)。再次告诉你的同事吧,你不用去管那个委托了,因为你现在拿到的Mode.Article对象中看不到那玩意,反正对你也没用。果然,看不见了,延迟加载的目的也达到鸟! 总结一下,本文讲的比前一篇文章讲的东西还少,主要记住三点: 1、把Category属性声明为虚拟的; 2、把Category原来的逻辑代码推迟到子类里面实现; 3、用子类(DModel.Acticle)实例话父类(Model.Acticle)。

  好了,用这个方法把项目里面类似Category这样的实体类属性修改为virtial吧,创建子类去重写它实现延迟加载,子类只有Dal层知道它的存在,Bll层和UI层对此一无所知,他们还是和原来一样用着,啥都不用修改,但是代码的效率明显有了提高,现在属性没有被使用就不会读取数据库了,数据库的压力也减少了^_^!!!

  这一切看起来似乎没问题,直到一个BUG被发现......在一个实体类中,有一个属性,按照之前的逻辑是我们给它赋值的时候,会对其他属性做相应的修改,现在给重写掉了,之前的逻辑,没拉.(待续)

时间: 2024-11-26 01:22:37

一起谈.NET技术,浅谈C#中的延迟加载(2)——善用virtual的相关文章

吴佰元:浅谈GPS技术在国土资源中的应用

[硅谷网9月26日讯]原文载于<科技与生活>杂志2012年第14期,文章称,社会在不断的前进与发展,当代信息化的时代里,对于各项技术的发展来讲,都是具有十分良好的前景与较大的发展空间.所以这些新技术的出现,为社会为人们的生活带来很多的便利.因此,在当代我们要充分利用这些新技术.新产品的力量推动我国各项事业不断前进的步伐. 关键词GPS技术:http://www.aliyun.com/zixun/aggregation/30834.html">国土资源:应用 国土资源是国民经济中

技术人员谈管理之浅谈团队管理

古语云":马,匹马徘徊,万马奔腾;人,单影单身难行,合群大成."团队是由一些拥有互补技能,为了共同目标而遵循共同方法和行为规则,相互承担责任的人组成的群体. 谈团队管理就不能不提人力资源管理,人力资源管理简单的理解就是管人,由于人才是企业最重要的财富,因此人力资源管理的重要性可想而知. 人力资源管理的过程包括如下4个方面: 1.      制定人力志愿计划 人力资源计划包括识别和记录项目角色.责任和汇报关系. 2.      组建项目团队 组建团队就是找人,为项目工作找到所需的人员以及

一起谈.NET技术,ASP.NET中如何正确使用Session

Asp.Net中的Session要比Asp中的Session灵活和强大很多,同时也复杂很多:看到有一些Asp.Net开发人员报怨说Session不稳定,莫名其妙的丢失,其实这正是Asp.Net改进的地方之一. 我们知道Session与Cookie最大的区别在于:Cookie信息全部存放于客户端,Session则只是将一个ID存放在客户端做为与服务端验证的标记,而真正的数据都是放在服务端的内存之中的. 在传统web编程语言(比如asp)中,session的过期完全是按照TimeOut来老老实实处理

一起谈.NET技术,从.NET中委托写法的演变谈开去(上):委托与匿名方法

在<关于最近面试的一点感想>一文中,Michael同学谈到他在面试时询问对方"delegate在.net framework1.1,2.0,3.5各可以怎么写"这个问题.于是乎,有朋友回复道"请问楼主,茴香豆的茴有几种写法","当代孔乙己",独乐,众乐.看了所有的评论,除了某些朋友认为"的确不该不知道这个问题"之外,似乎没有什么人在明确支持楼主. 不过我支持,为什么?因为我也提过出这样的问题. 这样,我们暂且不提应

一起谈.NET技术,从.NET中委托写法的演变谈开去(中):Lambda表达式及其优势

在上一篇文章中我们简单探讨了.NET 1.x和.NET 2.0中委托表现形式的变化,以及.NET 2.0中匿名方法的优势.目的及注意事项.那么现在我们来谈一下.NET 3.5(C# 3.0)中,委托的表现形式又演变成了什么样子,还有什么特点和作用. .NET 3.5中委托的写法(Lambda表达式) Lambda表达式在C#中的写法是"arg-list => expr-body","=>"符号左边为表达式的参数列表,右边则是表达式体(body).参数列表

偷也是门技术——浅谈XMLHTTP应用:新闻小偷[转]

xml 本文参考互联网整理而成(在此感谢资料奉献者).希望本文尽量系统,尽量易懂. 偷,即无劳而获.在网络上,诸如某大型权威站点发布了新闻,而自己的小小站点也想与时俱进,和人家一样同步更新,多N啊.于是,偷就是最好的办法了.偷是不道德的,不鼓励偷,但又不提倡不偷,都是技术惹的祸,扯远了~! 小偷程序是什么? 其实是通过XML中的XMLHTTP对象调用其它网站上的网页,甚至可以将接受的HTML代码进行过滤以获得需要内容(比如提取某某气象站,不可能是将整站提取显示,而只是需要显示天气的那部分). 其

民用报警服务技术浅谈

报警行业的设备和系统数字化.网络化的速度在加快,未来的报警服务行业市场是网络化的专属,传统的报警服务商业模式正在发生变化,通过卖产品和施工实现盈利的方式在弱化.在互联网时代,报警服务企业在实现技术变现的时候,更多要依靠服务去获得市场和用户的认可. 相对于传统的报警设备,网络化的报警设备在布线和安装上都有了长足的进步,加上IPC的软硬件,以及移动端的开发应用,如今的报警操作系统不仅使用方便,提高用户的使用体验,还改变了传统报警的样式,使得接警人员对报警区域进行可视化联动操作,降低误报率和报警运营中

一起谈.NET技术,关于C# 中的Attribute 特性

Attribute与Property 的翻译区别 Attribute 一般译作"特性",Property 仍然译为"属性". Attribute 是什么 Attribute 是一种可由用户自由定义的修饰符(Modifier),可以用来修饰各种需要被修饰的目标. 简单的说,Attribute就是一种"附着物" -- 就像牡蛎吸附在船底或礁石上一样. 这些附着物的作用是为它们的附着体追加上一些额外的信息(这些信息就保存在附着物的体内)-- 比如&qu

一起谈.NET技术,.Net语言中关于AOP 的实现详解

文章主要和大家讲解开发应用系统时在.Net语言中关于AOP 的实现.LogAspect完成的功能主要是将Advice与业务对象的方法建立映射,并将其添加到Advice集合中.由于我们在AOP实现中,利用了xml配置文件来配置PointCut,因此对于所有Aspect而言,这些操作都是相同的,只要定义了正确的配置文件,将其读入即可.对于Aspect的SyncProcessMessage(),由于拦截和织入的方法是一样的,不同的只是Advice的逻辑而已,因此在所有Aspect的公共基类中已经提供了

安卓AOP三剑客之Android APT技术浅谈

通过学习与使用square公司的开源项目javapoet,来实现仓库层动态生成代码 安卓AOP三剑客: APT, AspectJ, Javassist Android APT APT(Annotation Processing Tool 的简称),可以在代码编译期解析注解,并且生成新的 Java 文件,减少手动的代码输入.现在有很多主流库都用上了 APT,比如 Dagger2, ButterKnife, EventBus3 等 代表框架: DataBinding Dagger2 ButterKn