走进Linq-Linq to SQL源代码赏析之Provider的初始化2010-11-22 博客园 横刀天笑话说Linq to SQL理论上应该支持多种数据库的,而且应该支持多种数据库, 到最后却落的这个局面,是为了商业考虑还是本来技术就不成熟?不得而知。不 过不管怎么说Linq to SQL的体系结构确实是支持扩展的。在 System.Data.Linq.Mapping这个命名空间下微软提供了一个特性: ProviderAttribute,使用强类型的DataContext或使用Xml做映射的时候,该特 性可以用来指定具体的数据库提供者。如下:
[Database(“dbo.cnblogs”)]
[Provider(typeof(SqlProvider))]
Public CnBlogDataContext : DataContext
{
}
这就 表明我们的Linq to SQL是基于Sql Server了,SqlProvider是实现了 IProvider接口的(该接口存在于System.Data.Linq.Provider命名空间下)。在DataContext初始化时执行的Init方法里有这样几行代码:
if (model.ProviderType == null)
{
throw Error.ProviderTypeNull();
}
Type providerType = model.ProviderType;
if (!typeof(IProvider).IsAssignableFrom(providerType))
{
throw Error.ProviderDoesNotImplementRequiredInterface(providerType,
typeof(IProvider));
}
this.provider = (IProvider) Activator.CreateInstance(providerType);
this.provider.Initialize(this.services, connection);
这里是根据model的ProviderType 创建一个IProvider的实例。Model就是一个MetaModel对象。前面两篇都提到了 MetaModel有两个子类,AttributeMetaModel和XmlMetaModel,看看你是用哪种 方法做映射的,我们这里就用AttributeMetaModel做例子,在 AttributeMetaModel的构造函数里有这样几行代码:
ProviderAttribute[] customAttributes = (ProviderAttribute[]) this.contextType.
GetCustomAttributes(typeof(ProviderAttribute), true);
if ((customAttributes != null) && (customAttributes.Length == 1))
{
this.providerType = customAttributes[0].Type;
}
else
{
this.providerType = typeof(SqlProvider);
}
从DataContext类上找Provider 特性,如果没有找到就默认使用SqlProvider了。创建了IProvider的实例就会调 用它的Initialize方法进行初始化。Initialize方法需要两个参数IDataService 和一个连接对象(DbConnection或是连接字符串)。