随笔- 54  文章- 3  评论- 762  阅读- 39万 

   学习Linq to SQL也有一段时间了,感叹它做为ORM虽然简单但是功能效率都还不错,从编译器和语言层面支持上来看,它是其他ORM工具不能比的。Linq to SQL中运用了很多模式对自身的效率进行优化,其实这些模式是作为一个优秀ORM工具必备的,下面我将所我知道已经在Linq to SQL中实现的模式总结如下(如果要知道这些模式的具体内容,可以参考《企业应用架构模式》)。

  1.  A Unit of Work(工作单元模式)

     该模式主要用来跟踪对象的状态,比如从数据库里取出数据构成对象,这时候对象的值与数据库的数据是完全相同的,这些对象被标志为干净的(New)。当程序对某些对象的属性进行了修改后,这些对象被标志为脏的(Dirty)。在Linq to SQL中,使用基类为TrackedObject的对象来进行跟踪这些实体对象的状态改变(现在版本中只有StandardTrackedObject类继承了TrackedObject类)。当SubmitChanges时,遍历保存了所有TrackedObject对象的集合,根据它们自身的状态(如IsNew,IsDeleted,IsModified等)进行相应的操作。 这里使用Dictionary来保存TrackedObject,以实体对象为key,以TrackedObject对象为值,保证它们是一一对应的。

  2.  Identity Map (标志映射模式)

     该模式主要用来缓存已经读取过的对象,避免重复加载。如果我们以主键为条件进行查询,不管查询多少次,只有第一次是对数据库提交了查询,而后面查询出来的对象都是缓存的对象,我以前的文章中有提到,如Linq to SQL之查询和添加。在Linq to SQL中,使用IdentityCache的集合对实体对象进行缓存(private class IdentityCache<T, K>  它并没有直接包装使用Dictionary等,而是自己实现的hash查找及添加算法,不知道为什么要重新写一遍)。

  3.  Lazy Load (延迟加载模式)

     该模式解决的是用什么就取什么的问题,而不是一次就把数据全部取出来不管你需不需要。实现这种模式主要有四种方法:延迟初始化、虚代理、值保存对象和重影。Linq to SQL用最简单的延迟初始化的方法来实现该模式。当我们把实体对象的某属性标志为Delayed Loading时,该属性被声明为System.Data.Linq.Link<T>类型而不是通常的T类型,使用该值的时候大概这样:

if(this.value == null)
 
this.value = getValueFromDB();
return this.value;

当然这只是简单的逻辑,具体实现要复杂一些。

  其次对于集合类型的属性,比如Customer中包含Order的集合,以集合为单元进行延迟初始化而不是具体的每个对象。意思是使用该集合的时候一次性把所有集合数据取出来,这样能够有效解决加载波动的问题。想想看,如果每使用一个集合中的对象时才去到数据库中查询,会产生大量的数据库连接查询,反而使得效率降低。

 posted on   紫色阴影  阅读(2151)  评论(9编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
我要啦免费统计
点击右上角即可分享
微信分享提示