1.连接字符串的创建-Lazy.Framework从零开始设计自己的ORM架构

王朝学院·作者佚名  2016-08-28
窄屏简体版  字體: 小  |  中  |  大  |  超大  

开发初衷注册了博客园已经有几个月了,却从来都没有上来过,本人大概从2010年开始就开始做.NET 方向的开发。

这个是我在博客园发布的第一个帖子。 主要就是说说最近在写的一个ORM架构。

本人接触的ORM架构也有不少,没有一个是用着顺手的,要么就是配置起来特别吃力,要么就是使用起来不是很方便。 最终还是比较喜欢NHibernate这套架构,因为这套架构支持在Model表的实体类内部包含其他的表的实体类 也就是在使用的时候,连联表查询都可以省了 可以直接支持对象.对象的方式来进行查询数据,屡试不爽,有了它基本已经放弃了使用视图 或 联表查询等等。

但是用它也有不爽的地方,就是配置起来太麻烦,需要些HQL。

出于以上种种,想自己动手开发一套,高性能高效率的ORM架构。

废话不多说,下面开始说我的构思。、

初步设计开发一套架构的开始,总是要有一套架构的构思的。

对于这套架构,在实体类中舍去了xml文件的配置,使用了自定义特性。

1. 用户发起了一个添加对象的操作

2. 通过添加的该对象T,去缓存中获取T对象相关的全部自定义特性,如果缓存中不存在则获取该T对象的自定义特性存入缓存中

3. 找到T对象,在去缓存中获取T-sql语句 由于数据库不同,所以生成的Sql语句也不相同,如果不存在则新生成,然后放入缓存中。

4. 获取到了T-SQL语句后,使用T对象生成 DbParameter[] 使用Emit,动态的创建IL 创建获取T对象属性的方法,来进行将T 填充到DbParameter[]

5. 通过T对应的配置文件的数据库连接,实例化不同的数据库

6. 实例化数据库成功后 来进行执行插入

7. 如果插入的对象 T 是要缓存的话, 将会同时存入内存数据库

8. 上述描述的是 添加对象 并不包含获取对象 如果是获取对象的话,需要用到AOP 来实现 对象.对象

太专业的话也不会说,大概的流程是这样的一个流程,实现思路也大概有了一些,先从最底层开始写起,那就是配置文件中的数据库连接字符串

下面是Config 配置文件中的数据库连接字符串

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<connectionStrings>

<add name="Lazy1" connectionString="server=.=sa;pwd=Dieyu;database=Lazy.Framework;"PRoviderName="System.Data.SqlClient"/>

<add name="Lazy2" connectionString="server=.=sa;pwd=Dieyu;database=Lazy;" providerName="System.Data.SqlClient"/>

</connectionStrings>

</configuration>

下述代码 是先创建了 配置节点的接口

1///<summary>2///<para>代码说明:</para>3///<para>数据库连接字符串接口,用户存储数据库的连接字符串,主要应用于 配置文件的 connectionStrings 的节点数据库获取</para>4///<para>使用示例:</para>5///<para>无</para>6///</summary>7publicinterfaceILazyConfiguration8{9///<summary>10///<para>代码说明:</para>11///<para>用于设置获取该对象的唯一标识</para>12///<para>使用示例:</para>13///<para>无</para>14///</summary>15string Name {get;set; }16///<summary>17///<para>代码说明:</para>18///<para>用于设置数据库的连接字符串</para>19///<para>使用示例:</para>20///<para>如:ConnectionString = "server=.;uid=sa......省略"</para>21///</summary>22string ConnectionString {get;set; }23///<summary>24///<para>代码说明:</para>25///<para>用于设置该对象要连接数据库的类型</para>26///<para>使用示例:</para>27///<para>如:ProviderName = "System.Data.SqlClient"</para>28///</summary>29string ProviderName {get;set; }30///<summary>31///<para>代码说明:</para>32///<para>用于设置该对象要连接数据库的类型</para>33///<para>使用示例:</para>34///<para>如:DataType = DataType.System_Data_SqlClient</para>35///</summary>36 LazyDataTypeEnum DataType {get;set; }37 }

下面是集成了接口的配置类

1///<summary>2///<para>代码说明:</para>3///<para>数据库连接字符串对象,用户存储数据库的连接字符串,主要应用于 配置文件的 connectionStrings 的节点数据库获取</para>4///<para>使用示例:</para>5///<para>无</para>6///</summary>7internalpartialclassLazyConfiguration : ILazyConfiguration8{9///<summary>10///配置节点名称,此键唯一,不能拥有重复11///</summary>12publicstring Name {get;set; }13///<summary>14///<para>代码说明:</para>15///<para>配置节点字符串</para>16///<para>使用示例:</para>17///<para>如:ConnectionString = "server=.;uid=sa......省略"</para>18///</summary>19publicstring ConnectionString {get;set; }20///<summary>21///<para>代码说明:</para>22///<para>配置节点要连接的数据库驱动</para>23///<para>使用示例:</para>24///<para>如:ProviderName = "System.Data.SqlClient"</para>25///</summary>26publicstring ProviderName {get;set; }27///<summary>28///<para>代码说明:</para>29///<para>用于设置该对象要连接数据库的类型</para>30///<para>使用示例:</para>31///<para>如:DataType = DataType.System_Data_SqlClient</para>32///</summary>33public LazyDataTypeEnum DataType {get;set; }34 }

当配置节点类与接口都创建完成了后 由于是多个数据库连接串, 我们需要创捷 节点类的集合

1///<summary>2///<para>代码说明:</para>3///<para>配置节点访问集合,用来获取数据库连接字符串的节点信息</para>4///<para>使用示例:</para>5///<para>只提供程序集内部使用,外部访问无效</para>6///</summary>7publicclassLazyConfigurationCollection : IEnumerable8{9#region <<私有属性>>10///<summary>11///私有静态集合,用于保证全局唯一性12///</summary>13privatestatic IList<ILazyConfiguration> listLazyConfiguration =new List<ILazyConfiguration>();14#endregion1516#region <<公共属性>>17///<summary>18///<para>代码说明:</para>19///<para>通过索引获取一个ILazyConfiguration对象</para>20///<para>使用示例:</para>21///<para>如:ILazyConfiguration[0]</para>22///</summary>23///<param name="index">索引位置</param>24///<returns>ILazyConfiguration对象</returns>25public ILazyConfigurationthis[intindex]26{27get28{29returnlistLazyConfiguration[index];30}31}32///<summary>33///<para>代码说明:</para>34///<para>通过名称获取一个ILazyConfiguration对象</para>35///<para>使用示例:</para>36///<para>如:ILazyConfiguration["LazySql......."]</para>37///</summary>38///<param name="name">要获取连接字符串的名称</param>39///<returns>ILazyConfiguration对象</returns>40public ILazyConfigurationthis[stringname]41{42get43{44return listLazyConfiguration.FirstOrDefault(P => P.Name ==name);45}46}47///<summary>48///<para>代码说明:</para>49///<para>返回序列中的第一个元素;如果序列中不包含任何元素,则返回默认值。</para>50///<para>使用示例:</para>51///<para>无</para>52///</summary>53publicILazyConfiguration FirstOrDefaultConfiguration54{55get56{57return listLazyConfiguration.FirstOrDefault();

58 }

59 }

60 /// <summary>

61 /// <para>代码说明:</para>

62 /// <para>返回集合的总数</para>

63 /// <para>使用示例:</para>

64 /// <para>如:ILazyConfiguration.Count</para>

65 /// </summary>

66 public int Count

67 {

68 get

69 {

70 return listLazyConfiguration.Count;

71 }

72 }

73 #endregion

74

75 #region <<构造函数>>

76 /// <summary>

77 /// <para>代码说明:</para>

78 /// <para>实例化一个新的对象,该构造函数只能有程序集内部访问</para>

79 /// <para>使用示例:</para>

80 /// <para>无</para>

81 /// </summary>

82 internal LazyConfigurationCollection()

83 {

84 //无

85 }

86 #endregion

87

88 #region <<私有方法>>

89 /// <summary>

90 /// <para>代码说明:</para>

91 /// <para>向集合内添加一个对象</para>

92 /// <para>使用示例:</para>

93 /// <para>无</para>

94 /// </summary>

95 /// <param name="item">ILazyConfiguration对象</param>

96 internal void Add(ILazyConfiguration item)

97 {

98 listLazyConfiguration.Add(item);

99 }

100 #endregion

101

102 #region <<公共方法>>

103 /// <summary>

104 /// <para>代码说明:</para>

105 /// <para>返回一个循环访问集合的枚举器,可用于linq等查询</para>

106 /// <para>使用示例:</para>

107 /// <para>无</para>

108 /// </summary>

109 public IEnumerator GetEnumerator()

110 {

111 return listLazyConfiguration.GetEnumerator();

112 }

113 #endregion

114 }

节点集合创建完成后 , 我们需要一个单利模式, 来永远的保存着这些节点

1///<summary>2///<para>代码说明:</para>3///<para>获取配置节配置的数据库连接字符串,该类只会被全局实例化一次</para>4///<para>使用示例:</para>5///<para>LazyConfigurationProperty LazyConfigurationProperty = LazyConfigurationProperty.GetLazyConfigurationProperty()</para>6///</summary>7publicsealedclassLazyConfigurationProperty8{9#region <<私有属性>>10///<summary>11///创建全为唯一私有lazyConfigurationProperty 对象12///</summary>13privatestaticLazyConfigurationProperty lazyConfigurationProperty;14///<summary>15///程序运行时,创建一个静态只读的进程辅助对象16///</summary>17privatestaticreadonlyobject _object =newobject();18#endregion1920#region <<公共属性>>21///<summary>22///<para>代码说明:</para>23///<para>获取配置文件的配置节的集合</para>24///<para>使用示例:</para>25///<para>如:LazyConfigurations["xx"] or LazyConfigurations[i].....</para>26///</summary>27public LazyConfigurationCollection LazyConfigurations {get;privateset; }28#endregion2930#region <<构造函数>>31///<summary>32///构造方法私有,外键不能通过New类实例化此类33///</summary>34privateLazyConfigurationProperty() { }35#endregion3637#region <<公共方法>>38///<summary>39///<para>代码说明:</para>40///<para>单例模式,数据库配置对象, 全局唯一创建对象的入口</para>41///<para>使用示例:</para>42///<para>LazyConfigurationProperty LazyConfigurationProperty = LazyConfigurationProperty.GetLazyConfigurationProperty()</para>43///</summary>44///<returns>LazyConfigurationProperty全局唯一对象</returns>45publicstaticLazyConfigurationProperty GetLazyConfigurationProperty()46{47//先判断实例是否存在,不存在再加锁处理48if (lazyConfigurationProperty ==null)49{50//在同一时刻加了锁的那部分程序只有一个线程可以进入,51lock(_object)52{53//如实例不存在,则New一个新实例,否则返回已有实例54if (lazyConfigurationProperty ==null)55{56 lazyConfigurationProperty =newLazyConfigurationProperty();57//配置节点集合58 lazyConfigurationProperty.LazyConfigurations =newLazyConfigurationCollection();5960 //像LazyConfigurationCollection添加对象

61 var LazyConfigurationList = SettingConnectionStrings.GetConnectionStrings();

62 foreach (var item in LazyConfigurationList)

63 {

64 lazyConfigurationProperty.LazyConfigurations.Add(item);

65 }

66 }

67 }

68 }

69 return lazyConfigurationProperty;

70 }

71 #endregion

72 }

当此上述类被构建时 , 调用了下面类的方法, 将所有连接字符串 都装入上述类的集合中

1///<summary>2///<para>代码说明:</para>3///<para>配置文件对象初始化类,检查配置文件,初始化连接对象</para>4///<para>使用示例:</para>5///<para>如:SettingConnectionStrings.GetLazyConnectionStrings()</para>6///</summary>7internalsealedclassSettingConnectionStrings8{9///<summary>10///<para>代码说明:</para>11///<para>获取配置文件中的ConnectionStrings节中的全部数据中的Lazy配置集合</para>12///<para>使用示例:</para>13///<para>如:SettingConnectionStrings.GetLazyConnectionStrings()</para>14///</summary>15///<returns>返回Lazy配置集合</returns>16internalstatic IEnumerable<ConnectionStringSettings>GetLazyConnectionStrings()17{18//获取全部数据库连接19var _ConnectionStrings =ConfigurationManager.ConnectionStrings;20//获取数据库配置的连接字符串21var _LazyConnectionStrings = _ConnectionStrings.Cast<ConnectionStringSettings>().Where(P => P.Name.IndexOf("Lazy") ==0);22if (_LazyConnectionStrings.Count() <=0)23{24//如果未配置任何连接字符串,则出现此异常25thrownew ArgumentNullException("connectionStrings","在配置文件中, connectionStrings 节点,并不包含数据库连接字符串的配置, 要解决此错误,需要在配置文件中 connectionStrings 节点内添加 \"name\" 以 Lazy 开头的节点配置");26}2728return_LazyConnectionStrings;29}30///<summary>31///<para>代码说明:</para>32///<para>获取配置文件中的ConnectionStrings节中的全部数据中的Lazy配置集合</para>33///<para>使用示例:</para>34///<para>如:SettingConnectionStrings.GetConnectionStrings()</para>35///</summary>36///<returns>返回Lazy配置集合</returns>37internalstatic IList<ILazyConfiguration>GetConnectionStrings()38{39//获取节点集合40var _ConnectionStringSettingsList =GetLazyConnectionStrings();41//设置返回集合42 IList<ILazyConfiguration> _LazyConfigurationList =new List<ILazyConfiguration>();43foreach (ConnectionStringSettings connectionStringSettingsin_ConnectionStringSettingsList)44{45LazyDataTypeEnum _LazyDataType;46try47{48//将ProviderName转换成枚举,如果失败则触发异常49 _LazyDataType = (LazyDataTypeEnum)Enum.Parse(typeof(LazyDataTypeEnum),connectionStringSettings.ProviderName.Replace('.','_'));50}51catch52{53//如果无法转换为枚举 , 则引发异常.54 StringBuilder _ErrorMsg =newStringBuilder();

55 _ErrorMsg.Append("在位置文件中,connectionStrings 节点下的子节点,并不包含 \"ProviderName\" 的属性配置,或并不属于以下的一种:\n");

56 _ErrorMsg.Append("System.Data.Odbc\n");

57 _ErrorMsg.Append("System.Data.OleDb\n");

58 _ErrorMsg.Append("System.Data.OracleClient\n");

59 _ErrorMsg.Append("System.Data.SqlClient\n");

60 _ErrorMsg.Append("MySQL.Data.MySqlClient\n");

61 _ErrorMsg.Append(" 要解决此问题,请按此配置,如下\n");

62 _ErrorMsg.Append(" <add name=\"LazySqlConnection\" connectionString=\"server=....省略;\" providerName=\"System.Data.SqlClient\" />\n");

63 throw new ArgumentNullException("ProviderName", _ErrorMsg.ToString());

64 }

65

66 if (_LazyConfigurationList.Count(P => P.Name == connectionStringSettings.Name) > 0)

67 {

68 throw new ArgumentNullException("Name", "在配置文件中, connectionStrings 节点,存在相同 \"name\" 的节点.");

69 }

70

71 //添加集合

72 _LazyConfigurationList.Add(new LazyConfiguration()

73 {

74 ConnectionString = connectionStringSettings.ConnectionString,

75 Name = connectionStringSettings.Name,

76 ProviderName = connectionStringSettings.ProviderName,

77 DataType = _LazyDataType

78 });

79

80 }

81 return _LazyConfigurationList;

82 }

83 }

上面代码是写关于 配置连接字符串的存储

下面再放入一个数据库类型的枚举

1///<summary>2///<para>代码说明:</para>3///<para>数据库类型枚举</para>4///<para>使用示例:</para>5///<para>LazyDataTypeEnum.SQLServer</para>6///</summary>7publicenumLazyDataTypeEnum8{9///<summary>10///System.Data.Odbc11///</summary>12System_Data_Odbc,13///<summary>14///System.Data.OleDb15///</summary>16System_Data_OleDb,17///<summary>18///System.Data.OracleClient19///</summary>20System_Data_OracleClient,21///<summary>22///System.Data.SqlClient23///</summary>24System_Data_SqlClient,25///<summary>26///MySql.Data.MySqlClient27///</summary>28MySql_Data_MySqlClient2930 }

第一天,相关连接字符串的存储 就先写到这里 欢迎指点。

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航