Enterprise Library 的 数据访问应用块中:
Microsoft.Practices.EnterpriseLibrary.Data.Database 抽象类派生出了以下三个数据库类
public DbProviderMapping GetProviderMapping(string name, string dbProviderName)
{
DatabaseSettings settings = this.DatabaseSettings;
if (settings != null)
{
DbProviderMapping existingMapping = settings.ProviderMappings.Get(dbProviderName);
if (existingMapping != null)
{
return existingMapping;
}
}
Microsoft.Practices.EnterpriseLibrary.Data.Database 抽象类派生出了以下三个数据库类
Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase
Microsoft.Practices.EnterpriseLibrary.Data.Oracle.OracleDatabase
Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase
Microsoft.Practices.EnterpriseLibrary.Data.Oracle.OracleDatabase
Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase
从这一点知识我们就可以知道
Database dbSvc = DatabaseFactory.CreateDatabase();
上述代码创建的 dbSvc 并不是 Microsoft.Practices.EnterpriseLibrary.Data.Database 抽象类的实例,而应该是下面这三个类的其中一个实例。
Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase
Microsoft.Practices.EnterpriseLibrary.Data.Oracle.OracleDatabase
Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase
或者是你自己新写的一个派生自 Database 抽象类的子类。
Microsoft.Practices.EnterpriseLibrary.Data.Oracle.OracleDatabase
Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase
或者是你自己新写的一个派生自 Database 抽象类的子类。
我们再通过查看企业库的源代码简单看一下 DatabaseFactory.CreateDatabase 方法 是根据啥关系,来判断应该创建的是 Database 抽象类的那个子类。
分析代码可知,这里的判断分三步:
主要代码看 DatabaseCustomFactory.cs 文件的
public object CreateObject(IBuilderContext context, string name, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache)方法。
主要代码看 DatabaseCustomFactory.cs 文件的
public object CreateObject(IBuilderContext context, string name, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache)方法。
第一步:
在链接字符串中,我们可以根据链接字符串的 name 获得 链接字符串的 providerName 。
在链接字符串中,我们可以根据链接字符串的 name 获得 链接字符串的 providerName 。
第二步:
如果 我们设置了 providerName 的任何 影射关系, 则自动获得 这个映射的 DbProviderMapping ;
如果这个数据库访问者 没有被设置任何影射关系, 则 系统自动在默认提供的 SqlDatabase、 OracleDatabase 中匹配。
如果上述都没匹配出结果, 则 返回 GenericDatabase 。
如果 我们设置了 providerName 的任何 影射关系, 则自动获得 这个映射的 DbProviderMapping ;
如果这个数据库访问者 没有被设置任何影射关系, 则 系统自动在默认提供的 SqlDatabase、 OracleDatabase 中匹配。
如果上述都没匹配出结果, 则 返回 GenericDatabase 。
上述逻辑在 DatabaseConfigurationView.cs 文件中可以看到代码:
public DbProviderMapping GetProviderMapping(string name, string dbProviderName)
{
DatabaseSettings settings = this.DatabaseSettings;
if (settings != null)
{
DbProviderMapping existingMapping = settings.ProviderMappings.Get(dbProviderName);
if (existingMapping != null)
{
return existingMapping;
}
}
DbProviderMapping defaultMapping = this.GetDefaultMapping(name, dbProviderName);
if (defaultMapping != null)
{
return defaultMapping;
}
if (defaultMapping != null)
{
return defaultMapping;
}
return this.GetGenericMapping();
}
}
第三步
根据 DbProviderMapping 生成 Database 抽象类的实例。
根据 DbProviderMapping 生成 Database 抽象类的实例。
根据上述逻辑描述,我们就可以理解如下一个数据库的配置文件了。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<dataConfiguration defaultDatabase="MyTestConnectionString">
<providerMappings>
<add databaseType="Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
name="GenericDatabase" />
<add databaseType="Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
name="System.Data.SqlClient" />
</providerMappings>
</dataConfiguration>
<connectionStrings>
<add name="MyTestConnectionString" connectionString="server=(local)\SQLEXPRESS;database=EntLibQuickStarts;Integrated Security=true;"
providerName="GenericDatabase" />
</connectionStrings>
<system.data>
<DbProviderFactories>
<add name="my Generic Database" invariant="GenericDatabase" description="An alias for the SqlProvider" type="System.Data.SqlClient.SqlClientFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</DbProviderFactories>
</system.data>
</configuration>
<configuration>
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<dataConfiguration defaultDatabase="MyTestConnectionString">
<providerMappings>
<add databaseType="Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
name="GenericDatabase" />
<add databaseType="Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
name="System.Data.SqlClient" />
</providerMappings>
</dataConfiguration>
<connectionStrings>
<add name="MyTestConnectionString" connectionString="server=(local)\SQLEXPRESS;database=EntLibQuickStarts;Integrated Security=true;"
providerName="GenericDatabase" />
</connectionStrings>
<system.data>
<DbProviderFactories>
<add name="my Generic Database" invariant="GenericDatabase" description="An alias for the SqlProvider" type="System.Data.SqlClient.SqlClientFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</DbProviderFactories>
</system.data>
</configuration>
这个数据库配置文件生成的 Database dbSvc = DatabaseFactory.CreateDatabase();
dbSvc 必然是 Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase 类型的。
dbSvc 必然是 Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase 类型的。
注意:
system.data 数据节 的 DbProviderFactories 配置节 是给配置文件中 connectionStrings 节的 providerName 对应用的。
而 dataConfiguration 配置节的 providerMappings 是给 生成 的 是那一个 Database 抽象类的那一个实例用的。
system.data 数据节 的 DbProviderFactories 配置节 是给配置文件中 connectionStrings 节的 providerName 对应用的。
而 dataConfiguration 配置节的 providerMappings 是给 生成 的 是那一个 Database 抽象类的那一个实例用的。
参考资料:
没有评论:
发表评论