zoukankan      html  css  js  c++  java
  • 浅谈C#中的延“.NET研究”迟加载(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属性中获取到需要的数据。呵呵,由于我是写文章的人,所以觉得这个思路很好理解,但是看文字的您可能感觉有点晕,下面用代码来说明应该就清楚了。

      首先我们修改Mode上海徐汇企业网站设计与制作l.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被发现......在一个实体类中,有一个属性,按照之前的逻辑是我们给它赋值的时候,会对其他属性做相应的修改,现在给重写掉了,之前的逻辑,没拉.(待续)

  • 相关阅读:
    VisualSVN-Server windows 版安装时报错 "Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for more details."
    Pytest 单元测试框架之初始化和清除环境
    Pytest 单元测试框架入门
    Python(email 邮件收发)
    Python(minidom 模块)
    Python(csv 模块)
    禅道简介
    2020年最好的WooCommerce主题
    Shopify网上开店教程(2020版)
    WooCommerce VS Magento 2020:哪个跨境电商自建站软件更好?
  • 原文地址:https://www.cnblogs.com/waw/p/2213561.html
Copyright © 2011-2022 走看看