学习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的集合,以集合为单元进行延迟初始化而不是具体的每个对象。意思是使用该集合的时候一次性把所有集合数据取出来,这样能够有效解决加载波动的问题。想想看,如果每使用一个集合中的对象时才去到数据库中查询,会产生大量的数据库连接查询,反而使得效率降低。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?