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

简介:   很久以前就听过延迟加载这个东西,不过没有理解是什么意思,现在算是了解一二了,写点文章作为读书笔记,把自己的想法记录一下,希望对初学者帮助,不管是初学者或者高手如果发现文章那里写得不好或者有更好的思路和做法记得告诉我哦^^。

  很久以前就听过延迟加载这个东西,不过没有理解是什么意思,现在算是了解一二了,写点文章作为读书笔记,把自己的想法记录一下,希望对初学者帮助,不管是初学者或者高手如果发现文章那里写得不好或者有更好的思路和做法记得告诉我哦^^。文章打算写成两三篇,这个是第一篇。

  在三层结构中我们通常会使用多一个叫做模型层的东西,这一层中最主要做的事情是把数据库中的表 (或者其他数据源,例如xml或者自己定义的一种数据格式)转成对应的类,例如有一个文章表,这时候在这一层就会有一个文章类;文章类的属性对应着文章表的列,例如文章标题属性对应文章标题列。 实体类和数据表一一对应是最简单的情况,这时候实体类和实体类是各自独立存在的,没有出现相互引用的关系。 但是,几乎每一个数据库中的表都是存在关联关系的(关系型数据库),例如除了文章表之外,还会有一个文章分类表,假如说每一篇文章都必须属于一个分类,那么在数据库中表现出来的就是文章表中有一个外键字段指向文章分类表的主键 ,在C#代码中表示出来的是文章类中有一个属性(文章分类ID),通过这个属性我们就可以知道文章所属的分类、并且可以准确地通过代码查询数据库,获取一个文章分类实体类的对象,读取到文章所属分类的相关信息。

  以上的过程看起来一点问题都没有,整理一下思路,就是读取数据库,获取一个文章类对象,通过文字类对象中的文章分类ID的值,以这个值为查询条件去数据库中读取数据,获取一个文章分类对象,当然对数据库的操作我们通常 是封装在数据访问层中。然而从面向对象的角度考虑,我们会希望从文章类包含有文章分类的信息,用代码表示文章分类和文章两个实体类如下:

从上面的代码可以看到,在文章实体类中出现了一个Model.ArticleCategory类型的属性Category,我们想要的就是通过这个属性直接读取文章所属分类的详细信息。问题出现了,在数据库访问层中我们从数据库中读取数据去实例化一个文章实体类对象之后, 要选择在什么时候去给Category赋值

  • 选择一:立刻给通过分类ID(CategoryID属性)去获取所属文章分类的对象,然后塞给文章所属分类属性(Category) ,然后再返回文章对象。这种方法在有一点不好,就是万一得到文章对象之后根本不用去使用到Category属性显然这种做法不佳。
  • 选择二:在需要的时候再去读取文章分类,然后给文章类对象的Category属性赋值,但这和没有这个属性其实也没有什么区别。
  • 选择三:在Category属性的get访问器中实现读取数据库获取文章分类的代码,这样如果没有使用到Category属性的 时候是不会调用到这些代码的,也就不会去访问数据库拿东西了,为了避免每次访问Category属性都去读取数据库, 我们给他增加一个所有字段,得到的代码如下:
     
       
    c#代码

    protected Model.ArticleCategory _category;
    public Model.ArticleCategory Category
    {
    get
    {
    if (_category == null )
    {
    // 创建文章分类数据访问层对象
    Dal.ArticleCategory articleCategoryDal = new Dal.ArticleCategory();
    // 获取文章分类
    _category = articleCategoryDal.GetArticleCategoryByCategoryID(CategoryID);
    }
    return _category;
    }
    // set访问器就不需要了
    }

  乍看起来似乎没问题,但要考虑一点,在三层结构中数据的传输靠的就是模型层,模型层处于三层之下, 换句话说,模型层不会去引用三层中的任何一层,而上面代码中的GetArticleCategoryByCategoryID很显然是在三层之中,也许是在业务逻辑层或者数据访问层,所以...循环引用了,这种做法也不佳。如何实现对在文章类中对Category属性的数据进行延时加载呢?整理思路,根据需求一步步分析:

乍看起来似乎没问题,但要考虑一点,在三层结构中数据的传输靠的就是模型层,模型层处于三层之下,
换句话说,模型层不会去引用三层中的任何一层,而上面代码中的GetArticleCategoryByCategoryID很显然
是在三层之中,也行是在业务逻辑层或者数据访问层,所以...循环引用了,这种做法也不佳。
  • 首先:获取到一个文章类对象的时候,只有在读取了Category属性才去访问数据库,不读取是不访问的
  • 其次:读取同一个文章类对象的Category属性的时候只访问一次数据库
  • 最后:在Category属性的get访问器中我们不能调用三层中的方法(严格说是不直接显示调用)

  换个角度思考,我们能不能在数据访问层中读取数据、初始化一个文章类对象之后给它一个方法,告诉它如果你要 获取自己所属分类信息(文章分类对象)的时候就调用这个方法来拿,不用的时候就不去调用了,免得多链读取一次数据库。 给它一个方法,也就是说把方法传给它咯! 于是想到委托,我们可以在文章类中添加一个委托,这个委托的签名和通过文章分类ID获取文章分类对象 方法的签名一致,在Category属性的get访问器中调用这个委托,这样便解决了可以在get访问器中调用到方法去访问数据库, 也自然实现了延时加载!于是修改实体类代码如下:

 
 
c#代码

namespace Model
{
// 文章分类实体类
public class ArticleCategory
{
public int CategoryID { get ; set ; }
public string CategoryName { get ; set ; }
}
// 文章实体类
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 ; }

// 文章所属分类
protected Model.ArticleCategory _category;
public 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 ; }
}
}

  在文章读取数据库得到数据然后创建一个文章类对象之后,我们对CategoryLazyLoader进行赋值就OK了! 文章数据访问类中获取文章的方法大致如下:

 
 
c#代码

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

  通过上面方法得到的文章实体类对象中的Category属性就是实现了延时加载的了!
  文章写得不短,不过说的东西很简单,细想起来几乎没什么内容,一句话就是使用委托预先得到一个用于获取文章分类的方法,在文章分类属性的get选择器中调用委托返回结果。好了,告诉负责编写UI层代码的同事,调用了业务逻辑层的方法去获取文章实体类对象吧,! 已经帮你把文章分类给封装加进去了,而且使用了延迟加载,怎么实现你就不用管,用就行了!于是这个人用的时候囧了,文章实体类对象里面有个委托...... 委托啊!!!干嘛用的!!!???啥意思!

  先写到这里了,下一篇文章再说一些怎么隐藏这个委托,了解延迟加载的同学应该也想到方法了...

目录
相关文章
|
1天前
|
C#
c#委托详解
c#委托详解
6 0
|
10天前
|
人工智能 开发框架 量子技术
【专栏】.NET 技术:驱动创新的力量
【4月更文挑战第29天】.NET技术,作为微软的开发框架,以其跨平台、开源和语言多样性驱动软件创新。它在云计算、AI/ML、混合现实等领域发挥关键作用,通过Azure、ML.NET等工具促进新兴技术发展。未来,.NET将涉足量子计算、微服务和无服务器计算,持续拓宽软件开发边界,成为创新的重要推动力。掌握.NET技术,对于开发者而言,意味着握有开启创新的钥匙。
|
10天前
|
开发框架 .NET C#
【专栏】理解.NET 技术,提升开发水平
【4月更文挑战第29天】本文介绍了.NET技术的核心概念和应用,包括其跨平台能力、性能优化、现代编程语言支持及Web开发等特性。文章强调了深入学习.NET技术、关注社区动态、实践经验及学习现代编程理念对提升开发水平的重要性。通过这些,开发者能更好地利用.NET构建高效、可维护的多平台应用。
|
10天前
|
机器学习/深度学习 vr&ar 开发者
【专栏】.NET 技术:引领开发新方向
【4月更文挑战第29天】本文探讨了.NET技术如何引领软件开发新方向,主要体现在三方面:1) 作为跨平台开发的先锋,.NET Core支持多操作系统和移动设备,借助.NET MAUI创建统一UI,适应物联网需求;2) 提升性能和开发者生产力,采用先进技术和优化策略,同时更新C#语言特性,提高代码效率和可维护性;3) 支持现代化应用架构,包括微服务、容器化,集成Kubernetes和ASP.NET Core,保障安全性。此外,.NET还不断探索AI、ML和AR/VR技术,为软件开发带来更多创新可能。
|
10天前
|
开发框架 Cloud Native 开发者
【专栏】剖析.NET 技术的核心竞争力
【4月更文挑战第29天】本文探讨了.NET框架在软件开发中的核心竞争力:1) .NET Core实现跨平台与云原生技术的融合,支持多操作系统和容器化;2) 提升性能和开发者生产力,采用JIT、AOT优化,提供C#新特性和Roslyn编译器平台;3) 支持现代化应用架构,包括微服务和容器化,内置安全机制;4) 丰富的生态系统和社区支持,拥有庞大的开发者社区和微软的持续投入。这些优势使.NET在竞争激烈的市场中保持领先地位。
|
10天前
|
开发框架 .NET 开发者
【专栏】领略.NET 技术的创新力量
【4月更文挑战第29天】.NET技术自ASP.NET起历经创新,现以.NET Core为核心,展现跨平台能力,提升性能与生产力,支持现代化应用架构。.NET Core使开发者能用同一代码库在不同操作系统上构建应用,扩展至移动和物联网领域。性能提升,C#新特性简化编程,Roslyn编译器优化代码。拥抱微服务、容器化,内置安全机制,支持OAuth等标准。未来.NET 6将引入更快性能、Hot Reload等功能,预示着.NET将持续引领软件开发潮流,为开发者创造更多机会。
|
10天前
|
物联网 vr&ar 开发者
【专栏】.NET 技术:为开发注入活力
【4月更文挑战第29天】本文探讨了.NET技术的创新,主要体现在三个方面:1) .NET Core实现跨平台开发革命,支持多种操作系统和硬件,如.NET MAUI用于多平台UI;2) 性能提升与生产力飞跃,C#新特性简化编程,JIT和AOT优化提升性能,Roslyn提供代码分析工具;3) 引领现代化应用架构,支持微服务、容器化,内置安全机制。未来,.NET 7将带来更多新特性和前沿技术整合,如量子计算、AI,持续推动软件开发创新。开发者掌握.NET技术将赢得竞争优势。
|
10天前
|
人工智能 前端开发 Cloud Native
【专栏】洞察.NET 技术的开发趋势
【4月更文挑战第29天】本文探讨了.NET技术的三大发展趋势:1) 跨平台与云原生技术融合,通过.NET Core支持轻量级、高性能应用,适应云计算和微服务;2) 人工智能与机器学习的集成,如ML.NET框架,使开发者能用C#构建AI模型;3) 引入现代化前端开发技术,如Blazor,实现前后端一致性。随着.NET 8等新版本的发布,期待更多创新技术如量子计算、AR/VR的融合,.NET将持续推动软件开发的创新与进步。
|
4月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
46 0
|
14天前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
21 0