·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP.NET网站开发 >> 1.连接字符串的创建-Lazy.Framework从零开始设计自己的ORM架构

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

作者:佚名      ASP.NET网站开发编辑:admin      更新时间:2022-07-23

 开发初衷

  注册了博客园已经有几个月了,却从来都没有上来过,本人大概从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>
 7     public interface ILazyConfiguration
 8     {
 9         /// <summary>
10         /// <para>代码说明:</para>
11         /// <para>  用于设置获取该对象的唯一标识</para>
12         /// <para>使用示例:</para>
13         /// <para>  无</para>
14         /// </summary>
15         string Name { get; set; }
16         /// <summary>
17         /// <para>代码说明:</para>
18         /// <para>  用于设置数据库的连接字符串</para>
19         /// <para>使用示例:</para>
20         /// <para>  如:ConnectionString = "server=.;uid=sa......省略"</para>
21         /// </summary>
22         string ConnectionString { get; set; }
23         /// <summary>
24         /// <para>代码说明:</para>
25         /// <para>  用于设置该对象要连接数据库的类型</para>
26         /// <para>使用示例:</para>
27         /// <para>  如:ProviderName = "System.Data.SqlClient"</para>
28         /// </summary>
29         string 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>
 7     internal partial class LazyConfiguration : ILazyConfiguration
 8     {
 9         /// <summary>
10         /// 配置节点名称,此键唯一,不能拥有重复
11         /// </summary>
12         public string Name { get; set; }
13         /// <summary>
14         /// <para>代码说明:</para>
15         /// <para>  配置节点字符串</para>
16         /// <para>使用示例:</para>
17         /// <para>  如:ConnectionString = "server=.;uid=sa......省略"</para>
18         /// </summary>
19         public string ConnectionString { get; set; }
20         /// <summary>
21         /// <para>代码说明:</para>
22         /// <para>  配置节点要连接的数据库驱动</para>
23         /// <para>使用示例:</para>
24         /// <para>  如:ProviderName = "System.Data.SqlClient"</para>
25         /// </summary>
26         public string ProviderName { get; set; }
27         /// <summary>
28         /// <para>代码说明:</para>
29         /// <para>  用于设置该对象要连接数据库的类型</para>
30         /// <para>使用示例:</para>
31         /// <para>  如:DataType = DataType.System_Data_SqlClient</para>
32         /// </summary>
33         public LazyDataTypeEnum DataType { get; set; }
34     }

 

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

  1 /// <summary>
  2     /// <para>代码说明:</para>
  3     /// <para>  配置节点访问集合,用来获取数据库连接字符串的节点信息</para>
  4     /// <para>使用示例:</para>
  5     /// <para>  只提供程序集内部使用,外部访问无效</para>
  6     /// </summary>
  7     public class LazyConfigurationCollection : IEnumerable
  8     {
  9         #region <<私有属性>>
 10         /// <summary>
 11         /// 私有静态集合,用于保证全局唯一性
 12         /// </summary>
 13         private static IList<ILazyConfiguration> listLazyConfiguration = new List<ILazyConfiguration>();
 14         #endregion
 15 
 16         #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>
 25         public ILazyConfiguration this[int index]
 26         {
 27             get
 28             {
 29                 return listLazyConfiguration[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>
 40         public ILazyConfiguration this[string name]
 41         {
 42             get
 43             {
 44                 return listLazyConfiguration.FirstOrDefault(P => P.Name == name);
 45             }
 46         }
 47         /// <summary>
 48         /// <para>代码说明:</para>
 49         /// <para>  返回序列中的第一个元素;如果序列中不包含任何元素,则返回默认值。</para>
 50         /// <para>使用示例:</para>
 51         /// <para>  无</para>
 52         /// </summary>
 53         public ILazyConfiguration FirstOrDefaultConfiguration
 54         {
 55             get
 56             {
 57                 return 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>
 7     public sealed class LazyConfigurationProperty
 8     {
 9         #region <<私有属性>>
10         /// <summary>
11         /// 创建全为唯一私有lazyConfigurationProperty 对象
12         /// </summary>
13         private static LazyConfigurationProperty lazyConfigurationProperty;
14         /// <summary> 
15         /// 程序运行时,创建一个静态只读的进程辅助对象
16         /// </summary>
17         private static readonly object _object = new object();
18         #endregion
19 
20         #region <<公共属性>>
21         /// <summary>
22         /// <para>代码说明:</para>
23         /// <para>  获取配置文件的配置节的集合</para>
24         /// <para>使用示例:</para>
25         /// <para>  如:LazyConfigurations["xx"] or LazyConfigurations[i].....</para>
26         /// </summary>
27         public LazyConfigurationCollection LazyConfigurations { get; private set; }
28         #endregion
29 
30         #region <<构造函数>>
31         /// <summary>
32         /// 构造方法私有,外键不能通过New类实例化此类
33         /// </summary>
34         private LazyConfigurationProperty() { }
35         #endregion
36 
37         #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>
45         public static LazyConfigurationProperty GetLazyConfigurationProperty()
46         {
47             //先判断实例是否存在,不存在再加锁处理
48             if (lazyConfigurationProperty == null)
49             {
50                 //在同一时刻加了锁的那部分程序只有一个线程可以进入,
51                 lock (_object)
52                 {
53                     //如实例不存在,则New一个新实例,否则返回已有实例
54                     if (lazyConfigurationProperty == null)
55                     {
56                         lazyConfigurationProperty = new LazyConfigurationProperty();
57                         //配置节点集合
58                         lazyConfigurationProperty.LazyConfigurations = new LazyConfigurationCollection();
59 
60                         //像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>
 7     internal sealed class SettingConnectionStrings
 8     {
 9         /// <summary>
10         /// <para>代码说明:</para>
11         /// <para>  获取配置文件中的ConnectionStrings节中的全部数据中的Lazy配置集合</para>
12         /// <para>使用示例:</para>
13         /// <para>  如:SettingConnectionStrings.GetLazyConnectionStrings()</para>
14         /// </summary>
15         /// <returns>返回Lazy配置集合</returns>
16         internal static IEnumerable<ConnectionStringSettings> GetLazyConnectionStrings()
17         {
18             //获取全部数据库连接
19             var _ConnectionStrings = ConfigurationManager.ConnectionStrings;
20             //获取数据库配置的连接字符串
21             var _LazyConnectionStrings = _ConnectionStrings.Cast<ConnectionStringSettings>().Where(P => P.Name.IndexOf("Lazy") == 0);
22             if (_LazyConnectionStrings.Count() <= 0)
23             {
24                 //如果未配置任何连接字符串,则出现此异常
25                 throw new ArgumentNullException("connectionStrings", "在配置文件中, connectionStrings 节点,并不包含数据库连接字符串的配置, 要解决此错误,需要在配置文件中 connectionStrings 节点内添加 \"name\" 以 Lazy 开头的节点配置");
26             }
27 
28             return _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>
37         internal static IList<ILazyConfiguration> GetConnectionStrings()
38         {
39             //获取节点集合
40             var _ConnectionStringSettingsList = GetLazyConnectionStrings();
41             //设置返回集合
42             IList<ILazyConfiguration> _LazyConfigurationList = new List<ILazyConfiguration>();
43             foreach (ConnectionStringSettings connectionStringSettings in _ConnectionStringSettingsList)
44             {
45                 LazyDataTypeEnum _LazyDataType;
46                 try
47                 {
48                     //将ProviderName转换成枚举,如果失败则触发异常
49                     _LazyDataType = (LazyDataTypeEnum)Enum.Parse(typeof(LazyDataTypeEnum),connectionStringSettings.ProviderName.Replace('.', '_'));
50                 }
51                 catch
52                 {
53                     //如果无法转换为枚举 , 则引发异常.
54                     StringBuilder _ErrorMsg =new StringBuilder();
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>
 7     public enum LazyDataTypeEnum
 8     {
 9         /// <summary>
10         /// System.Data.Odbc
11         /// </summary>
12         System_Data_Odbc,
13         /// <summary>
14         /// System.Data.OleDb
15         /// </summary>
16         System_Data_OleDb,
17         /// <summary>
18         /// System.Data.OracleClient
19         /// </summary>
20         System_Data_OracleClient,
21         /// <summary>
22         /// System.Data.SqlClient
23         /// </summary>
24         System_Data_SqlClient,
25         /// <summary>
26         /// MySql.Data.MySqlClient
27         /// </summary>
28         MySql_Data_MySqlClient
29 
30     } 

 

 

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