走进Linq-Linq to SQL源代码赏析 Table的获取过程
[2] 走进Linq-Linq to SQL源代码赏析 Table
[3] 走进Linq-Linq to SQL源代码赏析 Table
系列文章导航:
不能不说的C#特性-迭代器(下),yield以及流的延迟计算
走进Linq-Linq to SQL How do I(1)
走进Linq-Linq to SQL How do I(2)
走进Linq-Linq to SQL How do I(3)
走进Linq-Linq to SQL源代码赏析 Table
走进Linq-Linq to SQL源代码赏析之Provider的初始化
走进Linq-Linq to SQL源代码赏析,通过Linq to SQL看Linq
关于设计模式的旁白
为什么Table<TEntity>类不使用单件模式?
一个数据库中有几个表,对于每个表对象(Table<TEntity>)我们希望它是单例的,但是系统中并不是只存在一个表对象。在这里微软一方面将表对象的构造函数设为私有的来防止客户端任意的使用new构造表对象的实例,而且没有提供任何公开的接口获取这个实例,另外一方面在DataContext里有一个Dictionary<MetaTable, ITable> tables的字典,用于缓存表对象。
这样就有这样的个示例:
{
//私有的构造函数
private Table()
{ }
}
public class DataContext()
{
private Dictionary<MetaTable, ITable> tables;
public DataContext()
{
this.tables = new Dictionary<MetaTable,ITable>();
}
public ITable GetTable(MetaTable metaTable)
{
ITable table = null;
if(!tables.TryGetValue(metaTable,out table)
{
//获取table对象
//将刚刚获取的table对象缓存起来,以备后用
tables.Add(metaTable,table);
}
return table;
}
}
又是一个不同于传统单件的单件模式,也许叫缓存模式更合适些。
关于抽象工厂
打开MetaModel的代码我们会看到,好家伙,有GetFunction方法,GetMetaType方法,GetTable方法,GetFunction方法返回MetaFunction,MetaFunction是一个抽象类,它有AttributeMetaFunction和MappedMetaFunction两个实现,AttributeMetaModel类中的GetFunction方法会返回AttributeMetaFunction,而MappedMetaFunction类里的GetFunction会返回MappedMetaFunction。呵呵,MetaModel好像是抽象工厂,而AttributeMetaModel和MappedMetaModel就是具体的工厂,而MetaFunction等都是抽象产品,AttributeMetaFunction都是具体产品:
将MetaTable,MetaFunction等的创建工作交给MetaModel去创建是非常合情合理的,MetaModel表达的是数据库和DataContext之间的映射,数据库当然最清楚它里面有几个表,几个存储过程和用户函数了,而且由于有两种配置映射的方式:Attribute和基于Xml的,那么就有两个不同系列的“产品”,如何能让创建出来的产品都一致(不会造成创建出一个AtttributeMetaFunction和一个MappedMetaTable来)呢?这就是抽象工厂的目的,抽象工厂可以创建一个产品家族,这样保证了产品是一个系列。
OK,对于DataContext的初始化和Table<TEntity>对象的获取的大致流程已经了解了,下一回我会在更广的层次来说明一下这些方面。主要涉及Provider的初始化。
源代码下载,本次源代码在上一篇的基础上又增加了几个涉及的相关类,并加有中文注释,各位可以下载下来在VS里便捷的浏览,注意:是编译不通过的