深入浅出学Linq-Linq to SQL DataContext的初始化

Linq是微软为大家提供的一个类库,在CLR层没有添加任何东西,那么这就让我们可以一窥Linq的全貌,Linq to Objects很简单,它的核心就是那些扩展方法,从今天起我们来赏析Linq to SQL的源代码。


话说DataContext是Linq to SQL的入口点,那么我们就从DataContext开始我们的赏析之旅吧。



Linq的构造函数(先看我们用的最多的那个):

Code


这两个设置非常重要,但是这里先不说了。

现在我们到InitWithDefaultMapping方法里:

Code


调用的是Init方法,看看Init方法:

Code


接受两个参数:一个连接对象,从前面可以看出这个连接对象可能是一个连接串,也可能是SQL Server Express的文件路径,还可以是一个IDbConnection对象。第二个参数是一个MappingSource类型的对象,这里就有点猫腻了。MappingSource(它是一个抽象类)是用来构建我们映射模型的,在Linq to SQL里提供两种映射方式:基于Attribute的和使用外部的XML配置文件。那么对应的,MappingSource就有两个子类:AttributeMappingSource和XmlMappingSource(我们还可以提供自己的映射方式)。

再回去看Init方法,它首先使用MappingSource的GetModel方法获得一个MetaModel对象。如果你使用Reflector展开System.Data.Linq.Mapping命名空间,你会发现这里有很多以Meta开头的抽象类:MetaModel,MetaTable,MetaFunction,这是干什么用的呢?还记得使用Attribute的时候有Database,Table,Function么?一个MetaModel就是描述一个数据库和一个DataContext类型(你可以继承这个类型)之间的映射模型,同理,MetaFunction就是存储过程或用户自定义函数与.NET的方法之间的映射模型。

我们来看看GetModel方法,它的内容很多,实际就一句话:

model = this.CreateModel(dataContextType)

调用MappingSource的另外一个方法CreateModel创建MetaModel对象,CreateModel是一个抽象方法,它是在AttributeMappingSource和XmlMappingSource里实现的。大家还可以看到MetaModel是个抽象类,它有各种实现。



关于源代码中设计模式的旁白



这里使用了什么设计模式呢?模板方法?好像有,工厂方法?好像也有。

 附件: 您所在的用户组无法下载或查看附件



MappingSource里有两个方法,GetModel方法是一个模板方法,定义了获得MetaModel对象的流程,实际上是调用抽象的CreateModel方法来实现的,CreateModel的实现在子类里。

再看下面这个图:

 附件: 您所在的用户组无法下载或查看附件

CreateModel是一个工厂方法,他们推迟到子类实现,在子类创建不同的产品,AttributeMappingSource里的CreateModel创建AttributeMetaModel类,XmlMappingSource里的CreateModel创建MappedMetaModel类。AttributeMetaModel和MappedMetaModel都继承自MetaModel类。


继续赏析我们的源代码

Code


Linq to SQL本是可以支持多种数据库的,对于这种场景当然是使用Provider Pattern了,这里的providerType就是数据库提供者,从model那里获取,我们就来看看AttributeMetaModel的构造函数里如何得到这个ProviderType:

Code


从DataContext类上Attribute,看看是否加了ProviderAttribute这个特性,该特性就是指定数据库提供者的,如果没有指定就默认的使用SqlProvider。我看到这个代码很兴奋,微软太开放了,扩展性这么好,呵呵。继续看Init中的代码:

Code


你指定的Provider必须实现了IProvider接口,但是,但是,可恶的微软居然把IProvider设为internal的,我气愤啊,我无助啊。

Init最后一句就是初始化数据库中的表了,不过这个方法只在强类型的DataContext中才有用,如果直接使用微软提供的DataContext是不会起作用的。



不知道微软上次发布的.NET Framework的源代码中有没有Linq的,反正我没找到,所以我用Reflctor还原了代码,然后自己建立了工程,这样你就可以借助VS快速的浏览代码了,不过不能编译。

我会从前到后把Linq to SQL的源代码都说一遍,这个过程是迭代进行的,每篇文章我会附带有文章涉及的代码,并加了我自己的注释。


(文/yuyijq  出处/博客园)

 感谢原创者的辛勤劳动,希望对您有所帮助,转载请注明原出处。
 您可能对 [Linq] 的这些文章也感兴趣:

LINQ体验(8)——Union All/Intersect/Top/Bottom/Paging/SqlMethods
LINQ To SQL && Lambda 使用方法小结
使用linq to xml 快速创建RSS
LINQ to SQL活学活用(4):监视你的一举一动
LINQ解 爱因斯坦迷题
LINQ to SQL 辅助工具
Creating custom LINQ provider using LinqExtender
Linq To Sql 项目从Beta迁移到RTM注意事项
LINQ体验(10)——LINQ语句之开放式并发控制和事务
使用LINQ TO SQL实现单表数据在DataGridView批编辑