走進Linq-Linq to SQL源代碼賞析之Provider的初始化
[2] 走進Linq-Linq to SQL源代碼賞析之Provider的初始化
[3] 走進Linq-Linq to SQL源代碼賞析之Provider的初始化
系列文章導航:
不能不說的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
話說Linq to SQL理論上應該支持多種數據庫的,而且應該支持多種數據庫,到最后卻落的這個局面,是為了商業考慮還是本來技術就不成熟?不得而知。不過不管怎么說Linq to SQL的體系結構確實是支持擴展的。
在System.Data.Linq.Mapping這個命名空間下微軟提供了一個特性:ProviderAttribute,使用強類型的DataContext或使用Xml做映射的時候,該特性可以用來指定具體的數據庫提供者。如下:
[Provider(typeof(SqlProvider))]
Public CnBlogDataContext : DataContext
{
}
這就表明我們的Linq to SQL是基于Sql Server數據庫了,SqlProvider是實現了IProvider接口的(該接口存在于System.Data.Linq.Provider命名空間下)。
在DataContext初始化時執行的Init方法里有這樣幾行代碼:
{
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的構造函數里有這樣幾行代碼:
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或是連接字符串)。