您的位置:知识库 » .NET技术

ORM映射框架总结--数据库操作库(精修版)

作者: 贺臣  来源: 博客园  发布时间: 2010-09-05 22:41  阅读: 11423 次  推荐: 2   原文链接   [收藏]  
摘要:在数据库操作中,都是ADO.NET进行数据库操作,但是对于对象的查询,都是泛化了的类型,也就是说我们不知道具体查询的是那张表,或者说是查询结果集是封装到那个对象,这就是本文要解决的问题。

1.       ORM数据库操作原理

前面已经介绍过了个人ORM映射框架中的三个核心库:

实体数据库 映射特性关系:

http://www.cnblogs.com/qingyuan/archive/2010/04/02/1702998.html

 实体分析器:

http://www.cnblogs.com/qingyuan/archive/2010/04/05/1704546.html

Sql 语句生成组建:

http://www.cnblogs.com/qingyuan/archive/2010/04/16/1713658.html

至于这篇文章也就是这四个组件中的最后一个了------- 数据库操作库。目前.net 中对于数据库操作的模板或组件太多了,先不说微软的Linq to SQL,Linq to Entity, 还有开源组织的Hibernate 克隆版NHibernate,以及前些天突然冒出来的ALinq, 号称压过Linq,有时间再研究一下。其实这些看是强大的组件框架,在其外表下面都是如出一辙,他们都是在ADO.NET 中进行的封装。

不过在这个数据库操作中,都是ADO.NET进行数据库操作,但是对于对象的查询,都是泛化了的类型,也就是说我们不知道具体查询的是那张表,或者说是查询结果集是封装到那个对象,这就是本文要解决的问题。

  2.       ADO.NET 介绍

感觉在这里进行ADO.NET的讲解似乎是多次一举,我相信ADO.NET是每个asp.net 程序员必会的基本技能。但是这里还是简单介绍其五个核心对象吧。

Connection: Connection 对象主要是开启程序和数据库之间的连结。没有利用连结对象将数据库打开,是无法从数据库中取得数据的。

CommandCommand 对象主要可以用来对数据库发出一些指令,例如可以对数据库下达查询、新增、修改、删除数据等指令,以及呼叫存在数据库中的预存程序等。

DataAdapter: DataSetCommand 对象主要是在数据源以及DataSet 之间执行数据传输的工作,它可以透过Command 对象下达命令后,并将取得的数据放入DataSet 对象中。

DataSetDataSet 这个对象可以视为一个暂存区(Cache),可以把从数据库中所查询到的数据保留起来,甚至可以将整个数据库显示出来。DataSet 的能力不只是可以储存多个Table 而已,还可以透过DataSetCommand 对象取得一些例如主键等的数据表结构,并可以记录数据表间的关联。DataSet 对象可以说是ADO.NET 中重量级的对象,这个对象架构在DataSetCommand 对象上,本身不具备和数据源沟通的能力。

DataReader: 当我们只需要循序的读取数据而不需要其它操作时,可以使用DataReader 对象。DataReader对象只是一次一笔向下循序的读取数据源中的数据,而且这些数据是只读的,并不允许作其它的操作。因为DataReader 在读取数据的时候限制了每次只读取一笔,而且只能只读,所以使用起来不但节省资源而且效率很好.

老生常谈的说了一遍ADO.NET 的五个核心对象,这里主要目的是为了更好的了解此篇文章。我想现在用Linq to SQL Linq to Entity 的人太多了,或许都忘记了ADO.NET 的基本操作,其实我本人也是如此,一段时间不是用好多忘记了,这里再次复习一遍ADO.NET 能更好的理解此篇文章。

  3.       数据库加载驱动操作接口

该数据库操作接口很简单,就是封装了一些数据库操作的常用接口和命令,并定义了一些数据库连接和关闭的方法,并控制了数据库事务提交和回滚的方法。不过在这里的方法实现中我并没有对事务进行处理,如果对本文有兴趣的人可以在后期的文章中关注,我会对此进行补充。

下面简单看看数据库加载驱动接口:

数据库加载驱动接口
 1 /**
 2  * 2010-2-2
 3  * 
 4  * 情 缘
 5  * 
 6  * 数据库提供加载驱动接口,该接口继承IDisposable,
 7  * 用于释放对象占用的内存。该接口定义了数据库链接
 8  * 语句,链接对象,执行命令,适配器模式接口。同时
 9  * 还提供了打开数据库连接和关闭的方法,还有三个方
10  * 法是用于控制数据库操作事务
11  * 
12  * */
13 
14  using System;
15  using System.Collections.Generic;
16  using System.Linq;
17  using System.Text;
18  using System.Data;
19 
20  namespace CommonData.Data.Core
21 {
22     public interface IDbProvider:IDisposable
23     {
24         /// <summary>
25         /// 数据库链接语句
26         /// </summary>
27          string ConnectionString { getset; }
28 
29         /// <summary>
30         /// 数据库连接对象
31         /// </summary>
32          IDbConnection Connection { getset; }
33 
34         /// <summary>
35         /// 数据库操作命令
36         /// </summary>
37          IDbCommand Command { getset; }
38 
39         /// <summary>
40         /// 数据库操作适配器
41         /// </summary>
42          IDbDataAdapter Adapter { getset; }
43 
44         /// <summary>
45         /// 打开数据库连接方法
46         /// </summary>
47          void Open();
48 
49         /// <summary>
50         /// 关闭数据库连接方法
51         /// </summary>
52          void Close();
53 
54         /// <summary>
55         /// 开始事务控制方法
56         /// </summary>
57          void BeginTransaction();
58 
59         /// <summary>
60         /// 事务回滚方法
61         /// </summary>
62          void RollBack();
63 
64         /// <summary>
65         /// 事务提交方法
66         /// </summary>
67          void Commit();
68     }
69 }
70  

这里数据库操作的常用对象都是采用的顶层的接口作为属性。至于为什么使用接口,它的好处已经说的太多了,次数也很多了,这里就不再多说。而public interface IDbProvider:IDisposable 集成这个接口,让程序自动管理对象,释放对象占用内存空间。

简单的看看SQL Server 数据库加载驱动操作类:

SQL Server 数据库加载驱动操作类
  1 /**
  2  * 2010-2-2
  3  * 
  4  * 情 缘
  5  * 
  6  * SQL Server 数据库操作基本对象
  7  * 该类实现了IDbProvider 接口。
  8  * 
  9  * */
 10  using System;
 11  using System.Collections.Generic;
 12  using System.Linq;
 13  using System.Text;
 14  using System.Data.SqlClient;
 15  using System.Data;
 16 
 17  namespace CommonData.Data.Core.SQLCore
 18 {
 19     public class SqlProvider : IDbProvider
 20     {
 21         private string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["DataBaseConfig"].ConnectionString;
 22         /// <summary>
 23         /// 数据库连接字符串
 24         /// </summary>
 25          public string ConnectionString
 26         {
 27             get
 28             {
 29                 if (connectionString == null)
 30                 {
 31                     connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["DataBaseConfig"].ConnectionString;
 32                 }
 33                 return connectionString;
 34             }
 35             set
 36             {
 37                 connectionString = value;
 38             }
 39         }
 40 
 41         private IDbConnection connection = null;
 42         /// <summary>
 43         /// 数据库连接对象
 44         /// </summary>
 45          public IDbConnection Connection
 46         {
 47             get
 48             {
 49                 if (connection == null)
 50                 {
 51                     connection = new SqlConnection(connectionString);
 52                 }
 53                 return connection;
 54             }
 55             set
 56             {
 57                 connection = value;
 58             }
 59         }
 60 
 61         private IDbCommand command = null;
 62         /// <summary>
 63         /// 数据库命令操作对象
 64         /// </summary>
 65          public IDbCommand Command
 66         {
 67             get
 68             {
 69                 if (command == null)
 70                 {
 71                     command = new SqlCommand();
 72                     command.Connection = connection;
 73                 }
 74                 return command;
 75             }
 76             set
 77             {
 78                 command = value;
 79             }
 80         }
 81 
 82         private IDbDataAdapter adapter = null;
 83         /// <summary>
 84         /// 数据库适配器对象
 85         /// </summary>
 86          public IDbDataAdapter Adapter
 87         {
 88             get
 89             {
 90                 if (adapter == null)
 91                 {
 92                     adapter = new SqlDataAdapter(command as SqlCommand);
 93                 }
 94                 return adapter;
 95             }
 96             set
 97             {
 98                 adapter = value;
 99             }
100         }
101 
102         /// <summary>
103         /// 数据库事务对象
104         /// </summary>
105          private IDbTransaction transaction = null;
106 
107         /// <summary>
108         /// 打开数据库连接
109         /// </summary>
110          public void Open()
111         {
112             if (connection != null)
113             {
114                 connection.Open();
115             }
116         }
117 
118         /// <summary>
119         /// 关闭数据库连接
120         /// </summary>
121          public void Close()
122         {
123             if (connection != null)
124             {
125                 connection.Close();
126             }
127         }
128 
129         /// <summary>
130         /// 开始事务
131         /// </summary>
132          public void BeginTransaction()
133         {
134             transaction = connection.BeginTransaction();
135             command.Transaction = transaction;
136         }
137 
138         /// <summary>
139         /// 事务回滚
140         /// </summary>
141         public void RollBack()
142         {
143             if (transaction != null)
144             {
145                 transaction.Rollback();
146                 command.Transaction = null;
147                 transaction.Dispose();
148             }
149         }
150 
151         /// <summary>
152         /// 事务提交
153         /// </summary>
154         public void Commit()
155         {
156             if (transaction != null)
157             {
158                 transaction.Commit();
159                 command.Transaction = null;
160                 transaction.Dispose();
161             }
162         }
163 
164         /// <summary>
165         /// 创建数据库加载驱动
166         /// </summary>
167         /// <returns></returns>
168         public IDbProvider CreateInstance()
169         {
170             return new SqlProvider();
171         }
172 
173         /// <summary>
174         /// 释放内存空间
175         /// </summary>
176         public void Dispose()
177         {
178             GC.SuppressFinalize(this);
179         }
180     }
181 }
182 

对于其他的数据库来说,使用操作的对象和命令都不同,他是它们都提供抽象出来了一个公共接口就是IDbProvider (数据提供加载驱动)。在接口中定义的每个get set 方法都进行了实现实现了一个属性的封装,并且提供了唯一对象的变量。(C#中属性的封装其实也就是一个getset方法,所以在接口中能够这样定义方法)

  4.       数据库的操作命令

ADO.NET 中查询数据库,返回的结果分为多种情况,而数据库的操作无非就四种情况增删改查.

而这四种情况又可以分为两大类:

(1). 数据库的修改操作: 数据的增加,修改,删除都对数据进行了操作,都有写的动作,对数据结构有了变动。

(2). 数据库的查询操作:数据库的查询,也就是读取数据,这个操作不会对数据的数据结构进行修改,因此这里可以单独分为一类。当然一类也就是比较复杂的一类了,查询的情况会很多不同。

下面是数据库操作的接口:

数据库操作的接口
  1 /**
  2  * 2010-3-5
  3  * 
  4  * 情 缘
  5  * 
  6  * 该接口定义了数据库操作的各种方法,该接口定义
  7  * 工作职责比较明确,只是针对数据的操作,不需要
  8  * 管理数据库的连接等过程。此接口还包含了一个数
  9  * 据流和集合类型的转换的方法定义
 10  * 
 11  * */
 12 using System;
 13 using System.Collections.Generic;
 14 using System.Linq;
 15 using System.Text;
 16 using System.Data;
 17 
 18 namespace CommonData.Data.Core
 19 {
 20     public interface IBaseHelper:IDisposable
 21     {
 22         /// <summary>
 23         /// 返回受影响行数
 24         /// </summary>
 25         /// <param name="provider">数据提供加载驱动</param>
 26         /// <param name="sqlString">sql语句</param>
 27         /// <returns></returns>
 28         int ExecuteNonQuery(IDbProvider provider, string sqlString);
 29 
 30         /// <summary>
 31         /// 返回受影响行数
 32         /// </summary>
 33         /// <param name="provider">数据提供加载驱动</param>
 34         /// <param name="sqlString">sql语句</param>
 35         /// <param name="isProcedure">是否为存储过程</param>
 36         /// <returns></returns>
 37         int ExecuteNonQuery(IDbProvider provider, string sqlString, bool isProcedure);
 38 
 39         /// <summary>
 40         /// 返回受影响行数
 41         /// </summary>
 42         /// <param name="provider">数据提供加载驱动</param>
 43         /// <param name="sqlString">sql语句</param>
 44         /// <param name="param">sql语句对应参数</param>
 45         /// <returns></returns>
 46         int ExecuteNonQuery(IDbProvider provider, string sqlString, params IDataParameter[] param);
 47 
 48         /// <summary>
 49         /// 返回受影响行数
 50         /// </summary>
 51         /// <param name="provider">数据提供加载驱动</param>
 52         /// <param name="sqlString">sql语句</param>
 53         /// <param name="isProcedure">是否为存储过程,true 为存储过程</param>
 54         /// <param name="param">sql语句对应参数</param>
 55         /// <returns></returns>
 56         int ExecuteNonQuery(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param);
 57 
 58         /// <summary>
 59         /// 返回查询语句第一行第一列
 60         /// </summary>
 61         /// <param name="provider">数据提供加载驱动</param>
 62         /// <param name="sqlString">sql语句</param>
 63         /// <returns></returns>
 64         object ExecuteScalar(IDbProvider provider, string sqlString);
 65 
 66         /// <summary>
 67         /// 返回查询语句第一行第一列
 68         /// </summary>
 69         /// <param name="provider">数据提供加载驱动</param>
 70         /// <param name="sqlString">sql语句</param>
 71         /// <param name="isProcedure">是否是存储过程</param>
 72         /// <returns></returns>
 73         object ExecuteScalar(IDbProvider provider, string sqlString, bool isProcedure);
 74 
 75         /// <summary>
 76         /// 返回查询语句第一行第一列
 77         /// </summary>
 78         /// <param name="provider">数据提供加载驱动</param>
 79         /// <param name="sqlString">sql语句</param>
 80         /// <param name="param">sql语句对应输入参数</param>
 81         /// <returns></returns>
 82         object ExecuteScalar(IDbProvider provider, string sqlString, params IDataParameter[] param);
 83 
 84         /// <summary>
 85         /// 返回查询语句第一行第一列
 86         /// </summary>
 87         /// <param name="provider">数据提供加载驱动</param>
 88         /// <param name="sqlString">sql语句</param>
 89         /// <param name="isProcedure">是否为存储过程</param>
 90         /// <param name="param">sql语句对应输入参数</param>
 91         /// <returns></returns>
 92         object ExecuteScalar(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param);
 93 
 94         /// <summary>
 95         /// 返回数据只读游标集
 96         /// </summary>
 97         /// <param name="provider">数据提供加载驱动</param>
 98         /// <param name="sqlString">sql语句</param>
 99         /// <returns></returns>
100         IDataReader ExecuteDataReader(IDbProvider provider, string sqlString);
101 
102         /// <summary>
103         /// 返回数据只读游标集
104         /// </summary>
105         /// <param name="provider">数据提供加载驱动</param>
106         /// <param name="sqlString">sql语句</param>
107         /// <param name="isProcedure">是否为存储过程</param>
108         /// <returns></returns>
109         IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, bool isProcedure);
110 
111         /// <summary>
112         /// 返回数据只读游标集
113         /// </summary>
114         /// <param name="provider">数据提供加载驱动</param>
115         /// <param name="sqlString">sql语句</param>
116         /// <param name="param">sql语句对应输入参数</param>
117         /// <returns></returns>
118         IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, params IDataParameter[] param);
119 
120         /// <summary>
121         /// 返回数据只读游标集
122         /// </summary>
123         /// <param name="provider">数据提供加载驱动</param>
124         /// <param name="sqlString">sql语句</param>
125         /// <param name="isProcedure">是否为存储过程</param>
126         /// <param name="param">sql语句对应输入参数</param>
127         /// <returns></returns>
128         IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param);
129 
130         /// <summary>
131         /// 获得数据表结构集合
132         /// </summary>
133         /// <param name="provider">数据提供加载驱动</param>
134         /// <param name="sqlString">sql语句</param>
135         /// <returns></returns>
136         DataTable ExecuteTable(IDbProvider provider, string sqlString);
137 
138         /// <summary>
139         ///  获得数据表结构集合
140         /// </summary>
141         /// <param name="provider">数据提供加载驱动</param>
142         /// <param name="sqlString">sql语句</param>
143         /// <param name="isProcedure">是否为存储过程</param>
144         /// <returns></returns>
145         DataTable ExecuteTable(IDbProvider provider, string sqlString, bool isProcedure);
146 
147         /// <summary>
148         /// 获得数据表结构集合
149         /// </summary>
150         /// <param name="provider">数据提供加载驱动</param>
151         /// <param name="sqlString">sql语句</param>
152         /// <param name="param">sql语句对应参数</param>
153         /// <returns></returns>
154         DataTable ExecuteTable(IDbProvider provider, string sqlString, params IDataParameter[] param);
155 
156         /// <summary>
157         /// 获得数据表结构集合
158         /// </summary>
159         /// <param name="provider">数据提供加载驱动</param>
160         /// <param name="sqlString">sql语句</param>
161         /// <param name="isProcedure">是否为存储过程</param>
162         /// <param name="param">sql语句对应参数</param>
163         /// <returns></returns>
164         DataTable ExecuteTable(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param);
165 
166 
167 
168         /// <summary>
169         /// 根据一个泛型类型获得实体对象
170         /// </summary>
171         /// <typeparam name="T">泛型类型</typeparam>
172         /// <param name="reader">只读数据流</param>
173         /// <returns></returns>
174         T ConvertToEntity<T>(IDataReader reader) where T : class ;
175 
176         /// <summary>
177         /// 将数据流装化为对象                                                
178         /// </summary>
179         /// <param name="type">转化的目标类型</param>
180         /// <param name="reader">只读数据流</param>
181         /// <returns></returns>
182         object ConvertToEntity(Type type,IDataReader reader);
183 
184         /// <summary>
185         /// 根据一个泛型类型查询一个集合
186         /// </summary>
187         /// <typeparam name="T">泛型类型</typeparam>
188         /// <param name="reader">只读数据流</param>
189         /// <returns></returns>
190         IList<T> ConvertToList<T>(IDataReader reader) where T : class;
191     }
192 }
193 

a).查询返回受影响的行数

           查询返回受影响的行数,主要针对于数据库的增删改三个动作,在这三个动作中都是修改了数据库的结构。而SQL Server是关系型数据库,对于数据库的修改都是以数据行的形式来修改的。所以在对数据库进行结构修改时,返回的都是受影响的数据行数。

           SQL Server返回受影响行数方法实现

SQL Server返回受影响行数方法实现
 1 /// <summary>
 2         /// 返回受影响行数
 3         /// </summary>
 4         /// <param name="provider">数据提供加载驱动</param>
 5         /// <param name="sqlString">sql语句</param>
 6         /// <returns></returns>
 7         public int ExecuteNonQuery(IDbProvider provider, string sqlString)
 8         {
 9             return ExecuteNonQuery(provider, sqlString, falsenull);
10         }
11 
12         /// <summary>
13         /// 返回受影响行数
14         /// </summary>
15         /// <param name="provider">数据提供加载驱动</param>
16         /// <param name="sqlString">sql语句</param>
17         /// <param name="isProcedure">是否为存储过程</param>
18         /// <returns></returns>
19         public int ExecuteNonQuery(IDbProvider provider, string sqlString, bool isProcedure)
20         {
21             return ExecuteNonQuery(provider, sqlString, isProcedure, null);
22         }
23 
24         /// <summary>
25         /// 返回受影响行数
26         /// </summary>
27         /// <param name="provider">数据提供加载驱动</param>
28         /// <param name="sqlString">sql语句</param>
29         /// <param name="param">sql语句对应参数</param>
30         /// <returns></returns>
31         public int ExecuteNonQuery(IDbProvider provider, string sqlString, params IDataParameter[] param)
32         {
33             return ExecuteNonQuery(provider, sqlString, false, param);
34         }
35 
36         /// <summary>
37         /// 返回受影响行数
38         /// </summary>
39         /// <param name="provider">数据提供加载驱动</param>
40         /// <param name="sqlString">sql语句</param>
41         /// <param name="isProcedure">是否为存储过程,true 为存储过程</param>
42         /// <param name="param">sql语句对应参数</param>
43         /// <returns></returns>
44         public int ExecuteNonQuery(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param)
45         {
46             provider.Connection.Open();
47             provider.Command.CommandText = sqlString;
48             if (isProcedure)
49             {
50                 provider.Command.CommandType = CommandType.StoredProcedure;
51             }
52             else
53             {
54                 provider.Command.CommandType = CommandType.Text;
55             }
56             provider.Command.Parameters.Clear();
57             provider.Command.Parameters.AddRange(param);
58             int line = (int)provider.Command.ExecuteNonQuery();
59             return line;
60         }

从上面的源码可以看出,其实最终所有的方法都指向了一个方法,而这个方法有个特殊的地方就是bool isProcedure,用此参数可以判断这个操作的是SQL 语句还是存储过程。在这个方法中还使用到了一个特殊的参数provider.Command.Parameters,而Parameters集合是没有AddRange()方法的(SqlParameters有这个方法),这个方法是使用的一个扩展方法,在.NET3.0 开始扩展方法为.NET 平台注入了新鲜的血液。让.NET 平台变的如此有魅力。

b).查询返回数据集的第一行第一列

           查询结果返回第一行第一列,我们用得最多的也就是聚合函数的使用了,聚合函数查询一般也就是查询返回一个结果。这里也就不再多讲解,看看方法实现的代码

查询结果返回第一行第一列
 1 /// <summary>
 2         /// 返回查询语句第一行第一列
 3         /// </summary>
 4         /// <param name="provider">数据提供加载驱动</param>
 5         /// <param name="sqlString">sql语句</param>
 6         /// <returns></returns>
 7         public object ExecuteScalar(IDbProvider provider, string sqlString)
 8         {
 9             return ExecuteScalar(provider, sqlString, falsenull);
10         }
11 
12         /// <summary>
13         /// 返回查询语句第一行第一列
14         /// </summary>
15         /// <param name="provider">数据提供加载驱动</param>
16         /// <param name="sqlString">sql语句</param>
17         /// <param name="isProcedure">是否是存储过程</param>
18         /// <returns></returns>
19         public object ExecuteScalar(IDbProvider provider, string sqlString, bool isProcedure)
20         {
21             return ExecuteScalar(provider, sqlString, isProcedure, null);
22         }
23 
24         /// <summary>
25         /// 返回查询语句第一行第一列
26         /// </summary>
27         /// <param name="provider">数据提供加载驱动</param>
28         /// <param name="sqlString">sql语句</param>
29         /// <param name="param">sql语句对应输入参数</param>
30         /// <returns></returns>
31         public object ExecuteScalar(IDbProvider provider, string sqlString, params IDataParameter[] param)
32         {
33             return ExecuteScalar(provider, sqlString, false, param);
34         }
35 
36         /// <summary>
37         /// 返回查询语句第一行第一列
38         /// </summary>
39         /// <param name="provider">数据提供加载驱动</param>
40         /// <param name="sqlString">sql语句</param>
41         /// <param name="isProcedure">是否为存储过程</param>
42         /// <param name="param">sql语句对应输入参数</param>
43         /// <returns></returns>
44         public object ExecuteScalar(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param)
45         {
46             provider.Connection.Open();
47             provider.Command.CommandText = sqlString;
48             if (isProcedure)
49             {
50                 provider.Command.CommandType = CommandType.StoredProcedure;
51             }
52             else
53             {
54                 provider.Command.CommandType = CommandType.Text;
55             }
56             provider.Command.Parameters.Clear();
57             provider.Command.Parameters.AddRange(param);
58             object result = provider.Command.ExecuteScalar();
59             return result;
60         }

c).查询返回只读数据流

           查询只读数据流,返回的就是IDataReader,ADO.NET 中查询返回只读数据流,是一种特别高效的读取数据的方式。作为.NET程序员我们一般都是使用的SqlDataReader 这个类,其实在程序架构的时候使用其父类接口IdataReader程序更具灵活性,而这里的IdataReader 实还有一个更重要的作用。那就是返回结果集合的时候,比如Ilist<T>。对于返回List<T> 结果在后面做介绍。

           返回IdataReader 源码

查询返回只读数据流
 1 /// <summary>
 2         /// 返回数据只读游标集
 3         /// </summary>
 4         /// <param name="provider">数据提供加载驱动</param>
 5         /// <param name="sqlString">sql语句</param>
 6         /// <returns></returns>
 7         public IDataReader ExecuteDataReader(IDbProvider provider, string sqlString)
 8         {
 9             return ExecuteDataReader(provider, sqlString, falsenull);
10         }
11 
12         /// <summary>
13         /// 返回数据只读游标集
14         /// </summary>
15         /// <param name="provider">数据提供加载驱动</param>
16         /// <param name="sqlString">sql语句</param>
17         /// <param name="isProcedure">是否为存储过程</param>
18         /// <returns></returns>
19         public IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, bool isProcedure)
20         {
21             return ExecuteDataReader(provider, sqlString, isProcedure, null);
22         }
23 
24         /// <summary>
25         /// 返回数据只读游标集
26         /// </summary>
27         /// <param name="provider">数据提供加载驱动</param>
28         /// <param name="sqlString">sql语句</param>
29         /// <param name="param">sql语句对应输入参数</param>
30         /// <returns></returns>
31         public IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, params IDataParameter[] param)
32         {
33             return ExecuteDataReader(provider, sqlString, false, param);
34         }
35 
36         /// <summary>
37         /// 返回数据只读游标集
38         /// </summary>
39         /// <param name="provider">数据提供加载驱动</param>
40         /// <param name="sqlString">sql语句</param>
41         /// <param name="isProcedure">是否为存储过程</param>
42         /// <param name="param">sql语句对应输入参数</param>
43         /// <returns></returns>
44         public IDataReader ExecuteDataReader(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param)
45         {
46             provider.Connection.Open();
47             provider.Command.CommandText = sqlString;
48             if (isProcedure)
49             {
50                 provider.Command.CommandType = CommandType.StoredProcedure;
51             }
52             else
53             {
54                 provider.Command.CommandType = CommandType.Text;
55             }
56             provider.Command.Parameters.Clear();
57             provider.Command.Parameters.AddRange(param);
58             IDataReader reader = provider.Command.ExecuteReader();
59             return reader;
60         }

d).查询返回DataTable

           DataTable 相当于内存中小型数据库的表,查询的数据库结果将以表的结构保存在内存中,这个是ADO.NET中断开式数据库链接操作数据的一种有效方式。对于这种方式,查询数据还是比较方便的,但是对于数据库的增删改用DataTable 就比较麻烦了,可以查看ADO.NET数据库操作的具体内容,这里不做多的介绍。

           查询返回DataTable 结果集源码

查询返回DataTable
 1 /// <summary>
 2         /// 获得数据表结构集合
 3         /// </summary>
 4         /// <param name="provider">数据提供加载驱动</param>
 5         /// <param name="sqlString">sql语句</param>
 6         /// <returns></returns>
 7         public DataTable ExecuteTable(IDbProvider provider, string sqlString)
 8         {
 9             return ExecuteTable(provider, sqlString, falsenull);
10         }
11 
12         /// <summary>
13         ///  获得数据表结构集合
14         /// </summary>
15         /// <param name="provider">数据提供加载驱动</param>
16         /// <param name="sqlString">sql语句</param>
17         /// <param name="isProcedure">是否为存储过程</param>
18         /// <returns></returns>
19         public DataTable ExecuteTable(IDbProvider provider, string sqlString, bool isProcedure)
20         {
21             return ExecuteTable(provider, sqlString, isProcedure, null);
22         }
23 
24         /// <summary>
25         /// 获得数据表结构集合
26         /// </summary>
27         /// <param name="provider">数据提供加载驱动</param>
28         /// <param name="sqlString">sql语句</param>
29         /// <param name="param">sql语句对应参数</param>
30         /// <returns></returns>
31         public DataTable ExecuteTable(IDbProvider provider, string sqlString, params IDataParameter[] param)
32         {
33             return ExecuteTable(provider, sqlString, false, param);
34         }
35 
36         /// <summary>
37         /// 获得数据表结构集合
38         /// </summary>
39         /// <param name="provider">数据提供加载驱动</param>
40         /// <param name="sqlString">sql语句</param>
41         /// <param name="isProcedure">是否为存储过程</param>
42         /// <param name="param">sql语句对应参数</param>
43         /// <returns></returns>
44         public DataTable ExecuteTable(IDbProvider provider, string sqlString, bool isProcedure, params IDataParameter[] param)
45         {
46             provider.Connection.Open();
47             provider.Command.CommandText = sqlString;
48             if (isProcedure)
49             {
50                 provider.Command.CommandType = CommandType.StoredProcedure;
51             }
52             else
53             {
54                 provider.Command.CommandType = CommandType.Text;
55             }
56             provider.Command.Parameters.Clear();
57             provider.Command.Parameters.AddRange(param);
58             DataSet ds = new DataSet();
59             provider.Adapter.Fill(ds);
60             return ds.Tables[0];
61         }

  5.       IdataReader 转换集合

上面提到了,这个ORM映射框架可以查询返回Ilist<T>,程序开发过程中我们往往喜欢使用List 结合,特别是泛型集合。上面的数据库操作其中一种返回的是IdataReader于是我们就想使用IdataReader 转换为List集合,或者List<T>泛型集合。但是这里遇到了一个问题,如果转换为List<T> 泛型集合,我们如果给泛型类型赋值,在这个数据库的操作过程中是进行了高度的抽象的,我们是无法知道操作的具体类型,因此我们想到的是使用反射机制,在前面提到过的实体分析器,我们使用实体分析器分析了实体的详细信息,并缓存在内存中。因此我们有了这个信息就可以很好的和数据库对应起来。这个转换的核心工作就是反射赋值,下面看看实现方式:

IdataReader 转换为 T 泛型实体类:

IdataReader 转换为 T 泛型实体类
 1 /// <summary>
 2         /// 根据一个泛型类型获得实体对象
 3         /// </summary>
 4         /// <typeparam name="T">泛型类型</typeparam>
 5         /// <param name="reader">只读数据流</param>
 6         /// <returns></returns>
 7         public T ConvertToEntity<T>(IDataReader reader) where T:class
 8         {
 9             T entity = default(T);
10             object result=ConvertToEntity(typeof(T),reader);
11             if (result != null)
12             {
13                 entity=(T)result;
14             }
15             return entity;
16         }
17 
18         /// <summary>
19         /// 将数据流装化为对象                                                
20         /// </summary>
21         /// <param name="type">转化的目标类型</param>
22         /// <param name="reader">只读数据流</param>
23         /// <returns></returns>
24         public object ConvertToEntity(Type type, IDataReader reader)
25         {
26             object entity = null;
27             if (reader.Read())
28             {
29                 entity = EntityFactory.CreateInstance(type);
30                 foreach (string key in EntityTypeCache.GetTableInfo(type).DicColumns.Keys)
31                 {
32                     if (string.IsNullOrEmpty(reader[key].ToString()))
33                     {
34                         EntityTypeCache.GetTableInfo(type).DicProperties[key].SetValue(entity, ""null);
35                     }
36                     else
37                     {
38                         EntityTypeCache.GetTableInfo(type).DicProperties[key].SetValue(entity, reader[key], null);
39                     }
40                 }
41                 if (EntityTypeCache.GetTableInfo(type).DicLinkTable.Keys.Count > 0)
42                 {
43                     foreach (string key in EntityTypeCache.GetTableInfo(type).DicLinkTable.Keys)
44                     {
45                         Type entityType = EntityTypeCache.GetTableInfo(type).DicLinkTable[key].DataType;
46                         string sql = Factory.CreateSingleSql(entityType);
47                         IDataParameter[] param = new IDataParameter[]{
48                             new SqlParameter()
49                         };
50                         param[0].ParameterName = "@" + EntityTypeCache.GetTableInfo(EntityTypeCache.GetTableInfo(type).DicLinkTable[key].DataType).Table.PrimaryKeyName;
51                         param[0].Value = EntityFactory.GetPropertyValue(entity, EntityTypeCache.GetTableInfo(type).DicLinkTable[key].KeyName);
52                         using (IDbProvider provider = new SqlProvider())
53                         {
54                             IDataReader read = ExecuteDataReader(provider, sql, param);
55                             object entityChild = EntityFactory.CreateInstance(entityType, false);
56                             if (read.Read())
57                             {
58                                 foreach (string propertyName in EntityTypeCache.GetTableInfo(entityType).DicProperties.Keys)
59                                 {
60                                     EntityTypeCache.GetTableInfo(entityType).DicProperties[propertyName].SetValue(entityChild, read[EntityTypeCache.GetTableInfo(entityType).DicColumns[propertyName].Name], null);
61                                 }
62                             }
63                             EntityTypeCache.GetTableInfo(type).DicProperties[key].SetValue(entity, entityChild, null);
64                         }
65                     }
66                 }
67             }
68             return entity;
69         }

IdataReader 转换为Ilist<T> 泛型集合:

IdataReader 转换为Ilist 泛型集合
 1 /// <summary>
 2         /// 根据一个泛型类型查询一个集合
 3         /// </summary>
 4         /// <typeparam name="T">泛型类型</typeparam>
 5         /// <param name="reader">只读数据流</param>
 6         /// <returns></returns>
 7         public IList<T> ConvertToList<T>(IDataReader reader) where T : class
 8         {
 9             T entity = default(T);
10             IList<T> list = new List<T>();
11             while (reader.Read())
12             {
13                 entity = EntityFactory.CreateInstance<T>();
14 
15                 foreach (string key in EntityTypeCache.GetTableInfo(typeof(T)).DicColumns.Keys)
16                 {
17                     if (string.IsNullOrEmpty(reader[key].ToString()))
18                     {
19                         EntityTypeCache.GetTableInfo(typeof(T)).DicProperties[key].SetValue(entity, nullnull);
20                     }
21                     else
22                     {
23                         EntityTypeCache.GetTableInfo(typeof(T)).DicProperties[key].SetValue(entity, reader[key], null);
24                     }
25                 }
26                 if (EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable.Keys.Count > 0)
27                 {
28                     foreach (string key in EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable.Keys)
29                     {
30                         Type entityType = EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable[key].DataType;
31                         string sql = Factory.CreateSingleSql(entityType);
32                         IDataParameter[] param = new IDataParameter[]{
33                             new SqlParameter()
34                         };
35                         param[0].ParameterName = "@" + EntityTypeCache.GetTableInfo(EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable[key].DataType).Table.PrimaryKeyName;
36                         param[0].Value = EntityFactory.GetPropertyValue(entity, EntityTypeCache.GetTableInfo(typeof(T)).DicLinkTable[key].KeyName);
37                         using (IDbProvider provider = new SqlProvider())
38                         {
39                             IDataReader read = ExecuteDataReader(provider, sql, param);
40                             object entityChild = EntityFactory.CreateInstance(entityType, false);
41                             if (read.Read())
42                             {
43                                 foreach (string propertyName in EntityTypeCache.GetTableInfo(entityType).DicProperties.Keys)
44                                 {
45                                     EntityTypeCache.GetTableInfo(entityType).DicProperties[propertyName].SetValue(entityChild, read[EntityTypeCache.GetTableInfo(entityType).DicColumns[propertyName].Name], null);
46                                 }
47                             }
48                             EntityTypeCache.GetTableInfo(typeof(T)).DicProperties[key].SetValue(entity, entityChild, null);
49                         }
50                     }
51                 }
52                 list.Add(entity);
53             }
54             return list;
55         }

对于T Ilist<T> 的转换其实是一样的过程。在这个转换的过程中有几个值得注意的地方。

    T entity = default(T);

default(T) 就好像我们实体对象赋初始值一样,在泛型中因为类型的不确定,所以语法规定了以这种方式赋初始值。

entity = EntityFactory.CreateInstance<T>(); 而这据代码是根据泛型类型创建了一个泛型实例,并在内存中分配空间。在这个里面定义了一个类,里面有很多方法,根据不同的情况,在动态创建对象,下面看看这个类的源码,感觉在对象抽象到一定程序的时候,这种动态创建对象的方式就非常有必要了。

动态创建对象的方式
  1 /**
  2  * 2010-1-28
  3  * 
  4  * 情 缘
  5  * 
  6  * 该实体类主要是通过反射机制来获取泛型实体类的实例的
  7  * 
  8  * 
  9  * */
 10 
 11 using System;
 12 using System.Reflection;
 13 
 14 
 15 namespace CommonData.Entity
 16 {
 17     public static class EntityFactory
 18     {
 19         /// <summary>
 20         /// 根据泛型类获取该泛型类的实例,
 21         /// T 泛型必须是class 类
 22         /// </summary>
 23         /// <typeparam name="T">泛型类</typeparam>
 24         /// <returns></returns>
 25         public static T CreateInstance<T>() where T :class
 26         {
 27             Type type = typeof(T);
 28             Object result;
 29             result = Activator.CreateInstance<T>();
 30             return (T)result;
 31         }
 32 
 33         /// <summary>
 34         /// 根据实体类型来创建实体实例
 35         /// </summary>
 36         /// <param name="type">要创建的对象的类型</param>
 37         /// <param name="nonPublic">如果有显示构造方法为true,如果没有显示构造方法为false</param>
 38         /// <returns></returns>
 39         public static object CreateInstance(Type type,bool nonPublic)
 40         {
 41            return Activator.CreateInstance(type,nonPublic);
 42         }
 43 
 44         /// <summary>
 45         /// 根据实体类型和相关参数构造实体实例
 46         /// </summary>
 47         /// <param name="type">要创建的对象的类型</param>
 48         /// <param name="param">与要调用构造函数的参数数量、顺序和类型匹配的参数数组。如果 param 为空数组,则调用不带任何参数的构造函数</param>
 49         /// <returns></returns>
 50         public static object CreateInstance(Type type,params object[] param)
 51         {
 52             return Activator.CreateInstance(type,param);
 53         }
 54 
 55         /// <summary>
 56         /// 根据实体公共接口获得特定属性名称的值
 57         /// </summary>
 58         /// <param name="entity">实体公共接口</param>
 59         /// <param name="name">实体属性名称</param>
 60         /// <returns></returns>
 61         public static object GetPropertyValue(IEntity entity, string name)
 62         {
 63             PropertyInfo property = entity.GetType().GetProperty(name);
 64             object result = null;
 65             if (property != null)
 66             {
 67                result = property.GetValue(entity, null);
 68             }
 69             return result;
 70         }
 71 
 72         /// <summary>
 73         /// 根据实体公共接口获得特定属性名称的值,这个属性是一个类
 74         /// </summary>
 75         /// <typeparam name="T">返回属性的泛型类型</typeparam>
 76         /// <param name="entity">实体公共接口</param>
 77         /// <param name="name">实体属性名称</param>
 78         /// <returns></returns>
 79         public static T GetPropertyValue<T>(IEntity entity, string name) where T:class
 80         {
 81             object result = GetPropertyValue(entity, name);
 82             if (result == null)
 83             {
 84                 return default(T);
 85             }
 86             else
 87             {
 88                 return (T)result;
 89             }
 90         }
 91 
 92         /// <summary>
 93         /// 获得实体属性值
 94         /// </summary>
 95         /// <param name="entity">实体类</param>
 96         /// <param name="name">属性名称</param>
 97         /// <returns></returns>
 98         public static object GetPropertyValue(object entity, string name)
 99         {
100             PropertyInfo property = entity.GetType().GetProperty(name);
101             object result = null;
102             if (property != null)
103             {
104                 result = property.GetValue(entity, null);
105             }
106             return result;
107         }
108 
109         /// <summary>
110         /// 根据实体公共接口设置某属性的值
111         /// </summary>
112         /// <param name="entity">实体公共接口</param>
113         /// <param name="name">实体属性名称</param>
114         /// <param name="value">实体属性值</param>
115         public static void SetPropertyValue(IEntity entity, string name, object value)
116         {
117             PropertyInfo property = entity.GetType().GetProperty(name);
118             if (property != null)
119             {
120                 property.SetValue(name,value,null);
121             }
122         }
123 
124         /// <summary>
125         /// 将某个值转化为特定的类型
126         /// </summary>
127         /// <param name="type">转化为的目标类型</param>
128         /// <param name="value">被转化的值</param>
129         /// <returns></returns>
130         public static object ConvertValue(Type type, object value)
131         {
132             if (value == DBNull.Value)
133             {
134                 return null;
135             }
136             return Convert.ChangeType(value,type);
137         }
138 
139         /// <summary>
140         /// 将某个值转化为特定的泛型类型
141         /// </summary>
142         /// <typeparam name="T">泛型类型</typeparam>
143         /// <param name="type">转化为的目标类型</param>
144         /// <param name="value">被转化的值</param>
145         /// <returns></returns>
146         public static T ConvertValue<T>(Type type, object value)
147         {
148             if (value == DBNull.Value)
149             {
150                 return default(T);
151             }
152             return (T)Convert.ChangeType(value, type);
153         }
154     }
155 }
156 

封装集合其实就是根据实体分析缓存的信息,查找对应的数据流中的数据,动态的给对象赋值。在这个动态赋值的过程中有个地方,特别应该注意:

if (string.IsNullOrEmpty(reader[key].ToString()))

这句话就是讲读取的数据转换为字符串,在之前也提到过,.NET 中的数据类型和SQL Server 中的数据类型是不同的,如果reader[key] 的值为null,如果我上面的这句判断改为

If(reader[key]==null) 那么这里就会存在一个潜在的bug,上面已经说过了,数据库中的类型和.NET 中的类型是不一样的,需要使用DbNull 这个对象。更多类容不再多少,可以到网上查看更多的资料。

这个里面还有一个特殊的过程,那就是级联查询,当然这里只是做了级联查询父类的操作,至于级联查询子类集合的过程没有做处理,这个在后期的改版中做修改。

  6.       下面举个小小的应用例子

没时间了,简单的介绍一下吧,不做详细的讲解了,后续在讲解。

在这个ORM框架中还定义了一个接口,源码如下:

数据库操作公共接口
  1 /**
  2  * 2010-2-26
  3  * 
  4  * 情 缘
  5  * 
  6  *  该接口定了实体增删改查的操作。
  7  *  接口中的定义都是使用实体的公共
  8  *  接口和泛型类型,这样确保了方法
  9  *  的公用性
 10  * 
 11  * */
 12 using System;
 13 using System.Collections.Generic;
 14 using System.Linq;
 15 using System.Text;
 16 using CommonData.Entity;
 17 using CommonData.Model.Core;
 18 
 19 namespace CommonData.Data.Core
 20 {
 21     public interface IDbHelper:IDisposable
 22     {
 23         /// <summary>
 24         /// 添加实体对象
 25         /// 将实体数据信息映射为一条插入sql语句
 26         /// </summary>
 27         /// <param name="entity">实体公共接口</param>
 28         /// <returns></returns>
 29         int Add(IEntity entity);
 30 
 31         /// <summary>
 32         /// 添加实体对象
 33         /// 将泛型数据信息映射为一条插入sql语句
 34         /// 该泛型类必须实现IEntity 接口
 35         /// </summary>
 36         /// <typeparam name="T">实体泛型类型</typeparam>
 37         /// <param name="t">泛型实体值</param>
 38         /// <returns></returns>
 39         int Add<T>(T t) where T : IEntity;
 40 
 41         /// <summary>
 42         /// 添加实体对象
 43         /// value 的类型必须和type一致,这样才能保存值
 44         /// </summary>
 45         /// <param name="type">实体类型</param>
 46         /// <param name="value">实体类型实例</param>
 47         /// <returns></returns>
 48         int Add(Type type, object value);
 49 
 50         /// <summary>
 51         /// 根据实体公共接口修改该实体信息
 52         /// 该实体是根据主键修改
 53         /// </summary>
 54         /// <param name="entity">实体公共接口</param>
 55         /// <returns></returns>
 56         int Update(IEntity entity);
 57 
 58         /// <summary>
 59         /// 根据实体的某个属性修改数据
 60         /// entity 中必须包含该属性,而且该属性的
 61         /// 值不能为空
 62         /// </summary>
 63         /// <param name="entity">实体公共接口</param>
 64         /// <param name="propertyName">实体属性名称</param>
 65         /// <returns></returns>
 66         int Update(IEntity entity,string propertyName);
 67 
 68         /// <summary>
 69         /// 根据实体的多个属性修改数据
 70         /// 数组中的属性名称必须存在.
 71         /// 传递参数数组不能为null
 72         /// </summary>
 73         /// <param name="entity">实体公共接口</param>
 74         /// <param name="propertyNames">属性名称数组</param>
 75         /// <returns></returns>
 76         int Update(IEntity entity,string[] propertyNames);
 77 
 78         /// <summary>
 79         /// 修改实体信息
 80         /// 该实体是根据主键修改
 81         /// </summary>
 82         /// <typeparam name="T">实体泛型类型</typeparam>
 83         /// <param name="t">泛型实例</param>
 84         /// <returns></returns>
 85         int Update<T>(T t) where T : IEntity;
 86 
 87         /// <summary>
 88         /// 根据泛型类的某个实体属性来修改该数据。
 89         /// 泛型实体实例中该属性不能为空
 90         /// </summary>
 91         /// <typeparam name="T">泛型类</typeparam>
 92         /// <param name="t">泛型实例</param>
 93         /// <param name="propertyName"></param>
 94         /// <returns></returns>
 95         int Update<T>(T t, string propertyName) where T : IEntity;
 96 
 97         /// <summary>
 98         /// 根据实体的多个属性修改数据
 99         /// 数组中的属性名称在泛型类中必须存在,
100         /// 数组不能传递null值
101         /// </summary>
102         /// <typeparam name="T">泛型类</typeparam>
103         /// <param name="t">泛型实例</param>
104         /// <param name="propertyNames">属性名称数组</param>
105         /// <returns></returns>
106         int Update<T>(T t, string[] propertyNames) where T : IEntity;
107 
108         /// <summary>
109         /// 修改实体信息
110         /// 该实体是根据主键修改
111         /// </summary>
112         /// <param name="type">实体类型</param>
113         /// <param name="value">实体对象实例</param>
114         /// <returns></returns>
115         int Update(Type type, object value);
116 
117         /// <summary>
118         /// 根据实体的某个属性来修改数据信息
119         /// 该方法使用Type 来确定需要修改的实体对象
120         /// value 实例中必须包含propertyName 这个属性
121         /// 而且propertyName 属性值不能为空
122         /// </summary>
123         /// <param name="type">实体类型</param>
124         /// <param name="value">实体实例</param>
125         /// <param name="propertyName">属性名称</param>
126         /// <returns></returns>
127         int Update(Type type, object value, string propertyName);
128 
129         /// <summary>
130         /// 根据实体的多个属性来修改数据信息
131         /// 该方法使用Type 来确定需要修改的实体对象
132         /// 数组中的属性名称在泛型类中必须存在,
133         /// 而且数组传递参数不能为null
134         /// </summary>
135         /// <param name="type">实体类型</param>
136         /// <param name="value">实体实例</param>
137         /// <param name="propertyNames">属性名称数组</param>
138         /// <returns></returns>
139         int Update(Type type,object value,string[] propertyNames);
140 
141         /// <summary>
142         /// 删除实体对象
143         /// 该方法是根据实体对象主键删除数据
144         /// </summary>
145         /// <param name="entity">实体公共接口</param>
146         /// <returns></returns>
147         int Delete(IEntity entity);
148 
149         /// <summary>
150         /// 根据某个实体属性删除数据
151         /// 该实体必须包含指定的属性名称
152         /// 而且实体属性值不能为空
153         /// </summary>
154         /// <param name="entity">实体属性公共接口</param>
155         /// <param name="propertyName">实体属性名称</param>
156         /// <returns></returns>
157         int Delete(IEntity entity, string propertyName);
158 
159         /// <summary>
160         /// 根据实体多个属性删除数据
161         /// 实体中必须包含该属性
162         /// 传递参数数组不能为空
163         /// </summary>
164         /// <param name="entity">实体属性公共接口</param>
165         /// <param name="propertyNames">实体属性名称数组</param>
166         /// <returns></returns>
167         int Delete(IEntity entity,string[] propertyNames);
168 
169         /// <summary>
170         /// 根据泛型类删除数据
171         /// 该方法是根据实体的主键删除的
172         /// </summary>
173         /// <typeparam name="T">泛型类</typeparam>
174         /// <param name="t">泛型实例</param>
175         /// <returns></returns>
176         int Delete<T>(T t) where T : class;
177 
178         /// <summary>
179         /// 根据泛型类的某个属性删除数据
180         /// 泛型类中必须存在该属性,而且
181         /// 属性值不能为空
182         /// </summary>
183         /// <typeparam name="T">泛型类型</typeparam>
184         /// <param name="t">泛型类实例</param>
185         /// <param name="propertyName">属性名称</param>
186         /// <returns></returns>
187         int Delete<T>(T t, string propertyName) where T : class;
188 
189         /// <summary>
190         /// 根据泛型类型的多个属性删除数据
191         /// 泛型类型中必须存在这些属性,传
192         /// 递参数的时候不能为null
193         /// </summary>
194         /// <typeparam name="T">泛型类</typeparam>
195         /// <param name="t">泛型实例</param>
196         /// <param name="propertyNames">属性名称数组</param>
197         /// <returns></returns>
198         int Delete<T>(T t, string[] propertyNames) where T : class;
199 
200         /// <summary>
201         /// 根据实体的类型删除数据。
202         /// value 中的类型由type确定
203         /// </summary>
204         /// <param name="type">实体类型</param>
205         /// <param name="value">实体对象实例</param>
206         /// <returns></returns>
207         int Delete(Type type, object value);
208 
209         /// <summary>
210         /// 根据实体的类型的某个属性删除数据。
211         /// value 中的类型由type确定
212         /// propertyName 属性名称必须在value 
213         /// 对象中存在
214         /// </summary>
215         /// <param name="type">实体类型</param>
216         /// <param name="value">实体对象实例</param>
217         /// <param name="propertyName">属性名称</param>
218         /// <returns></returns>
219         int Delete(Type type,object value,string propertyName);
220 
221         /// <summary>
222         /// 根据实体的类型的某个属性删除数据。
223         /// value 中的类型由type确定
224         /// propertyName 属性名称必须在value 
225         /// 对象中存在
226         /// </summary>
227         /// <param name="type">实体类型</param>
228         /// <param name="value">实体对象实例</param>
229         /// <param name="propertyNames">属性名称数组</param>
230         /// <returns></returns>
231         int Delete(Type type,object value,string[] propertyNames);
232 
233         /// <summary>
234         /// 根据主键查询实体对象
235         /// </summary>
236         /// <typeparam name="T">泛型类型</typeparam>
237         /// <param name="pkPropertyValue">主键值</param>
238         /// <returns></returns>
239         T GetEntity<T>(object pkPropertyValue) where T : class;
240 
241         /// <summary>
242         /// 根据实体类的类型和主键值查询实体对象
243         /// 使用 type 确定实体,主键确定数据的唯
244         /// 一性
245         /// </summary>
246         /// <param name="type">实体类型</param>
247         /// <param name="pkPropertyValue">主键值</param>
248         /// <returns></returns>
249         object GetEntity(Type type, object pkPropertyValue);
250 
251         /// <summary>
252         /// 根据某个实体的属性来查询实体对象
253         /// 该属性值能确定数据库唯一数据行
254         /// </summary>
255         /// <typeparam name="T">实体泛型类</typeparam>
256         /// <param name="propertyName">属性名称</param>
257         /// <param name="propertyValue">属性值</param>
258         /// <returns></returns>
259         T GetEntity<T>(string propertyName, object propertyValue) where T : class;
260 
261         /// <summary>
262         /// 根据某个实体的属性来查询实体对象
263         /// 该属性值能确定数据库唯一数据行
264         /// </summary>
265         /// <param name="type">实体类型</param>
266         /// <param name="propertyName">属性名称</param>
267         /// <param name="propertyValue">属性值</param>
268         /// <returns></returns>
269         object GetEntity(Type type, string propertyName, object propertyValue);
270 
271         /// <summary>
272         /// 根据某个实体的多个属性来查询实体对象
273         /// </summary>
274         /// <typeparam name="T">泛型类</typeparam>
275         /// <param name="entity">实体公共接口</param>
276         /// <param name="propertyNames">属性名称数组</param>
277         /// <returns></returns>
278         T GetEntity<T>(IEntity entity, string[] propertyNames) where T : class;
279 
280         /// <summary>
281         /// 根据某个实体的多个属性来查询实体对象
282         /// 实体根据type类型来确定
283         /// </summary>
284         /// <param name="type">实体类型</param>
285         /// <param name="entity">实体公共接口</param>
286         /// <param name="propertyNames">属性名称数组</param>
287         /// <returns></returns>
288         object GetEntity(Type type, IEntity entity, string[] propertyNames);
289 
290         /// <summary>
291         /// 查询该类型实体数据行数
292         /// </summary>
293         /// <param name="type">实体类型</param>
294         /// <returns></returns>
295         int GetCount(Type type);
296 
297         /// <summary>
298         /// 查询该类型实体数据行数
299         /// </summary>
300         /// <typeparam name="T">泛型类型</typeparam>
301         /// <returns></returns>
302         int GetCount<T>() where T : class;
303 
304         /// <summary>
305         /// 根据条件查询实体数据行数
306         /// </summary>
307         /// <param name="type">实体类型</param>
308         /// <param name="dic">实体属性键值对</param>
309         /// <param name="component">查询组件</param>
310         /// <returns></returns>
311         int GetCount(Type type, IDictionary<stringobject> dic, ConditionComponent component);
312 
313         /// <summary>
314         /// 查询所有实体集合
315         /// </summary>
316         /// <typeparam name="T">泛型类型</typeparam>
317         /// <returns></returns>
318         IList<T> GetList<T>() where T : class;
319 
320         /// <summary>
321         /// 根据某个实体属性查询实体集合
322         /// </summary>
323         /// <typeparam name="T">泛型类型</typeparam>
324         /// <param name="propertyName">属性名称</param>
325         /// <param name="value">属性值</param>
326         /// <returns></returns>
327         IList<T> GetList<T>(string propertyName, object value) where T : class;
328 
329         /// <summary>
330         /// 根据多个属性查询实体集合
331         /// </summary>
332         /// <typeparam name="T">泛型类型</typeparam>
333         /// <param name="entity">实体公共接口</param>
334         /// <param name="propertyNames">属性名称</param>
335         /// <returns></returns>
336         IList<T> GetList<T>(IDictionary<stringobject> dic) where T : class;
337 
338         /// <summary>
339         /// 根据多个属性查询实体集合
340         /// 该查询方式附加查询组建
341         /// </summary>
342         /// <typeparam name="T">类型类</typeparam>
343         /// <param name="dic">属性键值对</param>
344         /// <param name="component">查询组件</param>
345         /// <returns></returns>
346         IList<T> GetList<T>(IDictionary<stringobject> dic, ConditionComponent component) where T : class;
347     }
348 }
349 

上面的接口实现类:

数据库操作公共实体
  1 /**
  2  * 2010-2-26
  3  * 
  4  * 情 缘
  5  * 
  6  * 当前类实现了IDbHelper接口,主要用于对实体进行
  7  * 增删改查操作。
  8  * 
  9  * */
 10 using System;
 11 using System.Collections.Generic;
 12 using System.Linq;
 13 using System.Text;
 14 using CommonData.Entity;
 15 using System.Data;
 16 using CommonData.Model.Core;
 17 
 18 namespace CommonData.Data.Core.SQLCore
 19 {
 20     public class SqlHelper:IDbHelper
 21     {
 22         private IBaseHelper baseHelper;
 23         /// <summary>
 24         /// 数据库操作公共接口
 25         /// </summary>
 26         public IBaseHelper BaseHelper
 27         {
 28             get
 29             {
 30                 if (baseHelper == null)
 31                 {
 32                     baseHelper = new BaseHelper();
 33                 }
 34                 return baseHelper;
 35             }
 36             set 
 37             {
 38                 baseHelper = value;
 39             }
 40         }
 41 
 42         private IDbFactory factory;
 43         /// <summary>
 44         /// sql语句构造工厂对象
 45         /// </summary>
 46         public IDbFactory Factory
 47         {
 48             get
 49             {
 50                 if (factory == null)
 51                 {
 52                     factory = new SqlFactory();
 53                 }
 54                 return factory;
 55             }
 56             set
 57             {
 58                 factory = value;
 59             }
 60         }
 61 
 62 
 63         /// <summary>
 64         /// 添加实体对象
 65         /// 将实体数据信息映射为一条插入sql语句
 66         /// </summary>
 67         /// <param name="entity">实体公共接口</param>
 68         /// <returns></returns>
 69         public int Add(IEntity entity)
 70         {
 71             IDataParameter[] param = null;
 72             string sql = Factory.CreateInsertSql(entity,out param);
 73             using(IDbProvider provider=new SqlProvider())
 74             {
 75                 return BaseHelper.ExecuteNonQuery(provider,sql,param);
 76             }
 77         }
 78 
 79         /// <summary>
 80         /// 添加实体对象
 81         /// 将泛型数据信息映射为一条插入sql语句
 82         /// 该泛型类必须实现IEntity 接口
 83         /// </summary>
 84         /// <typeparam name="T">实体泛型类型</typeparam>
 85         /// <param name="t">泛型实体值</param>
 86         /// <returns></returns>
 87         public int Add<T>(T t) where T : IEntity
 88         {
 89             IDataParameter[] param = null;
 90             string sql = Factory.CreateInsertSql<T>(t,out param);
 91             using (IDbProvider provider = new SqlProvider())
 92             {
 93                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
 94             }
 95         }
 96 
 97         /// <summary>
 98         /// 添加实体对象
 99         /// value 的类型必须和type一致,这样才能保存值
100         /// </summary>
101         /// <param name="type">实体类型</param>
102         /// <param name="value">实体类型实例</param>
103         /// <returns></returns>
104         public int Add(Type type, object value)
105         {
106             IDataParameter[] param = null;
107             string sql = Factory.CreateInsertSql(type,value,out param);
108             using (IDbProvider provider = new SqlProvider())
109             {
110                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
111             }
112         }
113 
114         /// <summary>
115         /// 根据实体公共接口修改该实体信息
116         /// 该实体是根据主键修改
117         /// </summary>
118         /// <param name="entity">实体公共接口</param>
119         /// <returns></returns>
120         public int Update(IEntity entity)
121         {
122             IDataParameter[] param = null;
123             string sql = Factory.CreateUpdateSql(entity,out param);
124             using (IDbProvider provider = new SqlProvider())
125             {
126                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
127             }
128         }
129 
130         /// <summary>
131         /// 根据实体的某个属性修改数据
132         /// entity 中必须包含该属性,而且该属性的
133         /// 值不能为空
134         /// </summary>
135         /// <param name="entity">实体公共接口</param>
136         /// <param name="propertyName">实体属性名称</param>
137         /// <returns></returns>
138         public int Update(IEntity entity, string propertyName)
139         {
140             IDataParameter[] param = null;
141             string sql = Factory.CreateUpdateSql(entity, out param, propertyName);
142             using (IDbProvider provider = new SqlProvider())
143             {
144                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
145             }
146         }
147 
148         /// <summary>
149         /// 根据实体的多个属性修改数据
150         /// 数组中的属性名称必须存在.
151         /// 传递参数数组不能为null
152         /// </summary>
153         /// <param name="entity">实体公共接口</param>
154         /// <param name="propertyNames">属性名称数组</param>
155         /// <returns></returns>
156         public int Update(IEntity entity, string[] propertyNames)
157         {
158             IDataParameter[] param = null;
159             string sql = Factory.CreateUpdateSql(entity,out param,propertyNames);
160             using (IDbProvider provider = new SqlProvider())
161             {
162                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
163             }
164         }
165 
166         /// <summary>
167         /// 修改实体信息
168         /// 该实体是根据主键修改
169         /// </summary>
170         /// <typeparam name="T">实体泛型类型</typeparam>
171         /// <param name="t">泛型实例</param>
172         /// <returns></returns>
173         public int Update<T>(T t) where T : IEntity
174         {
175             IDataParameter[] param = null;
176             string sql = Factory.CreateUpdateSql(typeof(T),t,out param);
177             using (IDbProvider provider = new SqlProvider())
178             {
179                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
180             }
181         }
182 
183         /// <summary>
184         /// 根据泛型类的某个实体属性来修改该数据。
185         /// 泛型实体实例中该属性不能为空
186         /// </summary>
187         /// <typeparam name="T">泛型类</typeparam>
188         /// <param name="t">泛型实例</param>
189         /// <param name="propertyName"></param>
190         /// <returns></returns>
191         public int Update<T>(T t, string propertyName) where T : IEntity
192         {
193             IDataParameter[] param = null;
194             string sql = Factory.CreateUpdateSql(typeof(T), t, out param,propertyName);
195             using (IDbProvider provider = new SqlProvider())
196             {
197                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
198             }
199         }
200 
201         /// <summary>
202         /// 根据实体的多个属性修改数据
203         /// 数组中的属性名称在泛型类中必须存在,
204         /// 数组不能传递null值
205         /// </summary>
206         /// <typeparam name="T">泛型类</typeparam>
207         /// <param name="t">泛型实例</param>
208         /// <param name="propertyNames">属性名称数组</param>
209         /// <returns></returns>
210         public int Update<T>(T t, string[] propertyNames) where T : IEntity
211         {
212             IDataParameter[] param = null;
213             string sql = Factory.CreateUpdateSql(typeof(T), t, out param, propertyNames);
214             using (IDbProvider provider = new SqlProvider())
215             {
216                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
217             }
218         }
219 
220         /// <summary>
221         /// 修改实体信息
222         /// 该实体是根据主键修改
223         /// </summary>
224         /// <param name="type">实体类型</param>
225         /// <param name="value">实体对象实例</param>
226         /// <returns></returns>
227         public int Update(Type type, object value)
228         {
229             IDataParameter[] param = null;
230             string sql = Factory.CreateUpdateSql(type,value,out param);
231             using (IDbProvider provider = new SqlProvider())
232             {
233                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
234             }
235         }
236 
237         /// <summary>
238         /// 根据实体的某个属性来修改数据信息
239         /// 该方法使用Type 来确定需要修改的实体对象
240         /// value 实例中必须包含propertyName 这个属性
241         /// 而且propertyName 属性值不能为空
242         /// </summary>
243         /// <param name="type">实体类型</param>
244         /// <param name="value">实体实例</param>
245         /// <param name="propertyName">属性名称</param>
246         /// <returns></returns>
247         public int Update(Type type, object value, string propertyName)
248         {
249             IDataParameter[] param = null;
250             string sql = Factory.CreateUpdateSql(type, value, out param, propertyName);
251             using (IDbProvider provider = new SqlProvider())
252             {
253                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
254             }
255         }
256 
257         /// <summary>
258         /// 根据实体的多个属性来修改数据信息
259         /// 该方法使用Type 来确定需要修改的实体对象
260         /// 数组中的属性名称在泛型类中必须存在,
261         /// 而且数组传递参数不能为null
262         /// </summary>
263         /// <param name="type">实体类型</param>
264         /// <param name="value">实体实例</param>
265         /// <param name="propertyNames">属性名称数组</param>
266         /// <returns></returns>
267         public int Update(Type type, object value, string[] propertyNames)
268         {
269             IDataParameter[] param = null;
270             string sql = Factory.CreateUpdateSql(type, value, out param, propertyNames);
271             using (IDbProvider provider = new SqlProvider())
272             {
273                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
274             }
275         }
276 
277         
278         
279 
280         /// <summary>
281         /// 删除实体对象
282         /// 该方法是根据实体对象主键删除数据
283         /// </summary>
284         /// <param name="entity">实体公共接口</param>
285         /// <returns></returns>
286         public int Delete(IEntity entity)
287         {
288             IDataParameter[] param = null;
289             string sql = Factory.CreateDeleteSql(entity,out param);
290             using (IDbProvider provider = new SqlProvider())
291             {
292                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
293             }
294         }
295 
296         /// <summary>
297         /// 根据某个实体属性删除数据
298         /// 该实体必须包含指定的属性名称
299         /// 而且实体属性值不能为空
300         /// </summary>
301         /// <param name="entity">实体属性公共接口</param>
302         /// <param name="propertyName">实体属性名称</param>
303         /// <returns></returns>
304         public int Delete(IEntity entity, string propertyName)
305         {
306             IDataParameter[] param = null;
307             string sql = Factory.CreateDeleteSql(entity,out param,propertyName);
308             using (IDbProvider provider = new SqlProvider())
309             {
310                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
311             }
312         }
313 
314         /// <summary>
315         /// 根据实体多个属性删除数据
316         /// 实体中必须包含该属性
317         /// 传递参数数组不能为空
318         /// </summary>
319         /// <param name="entity">实体属性公共接口</param>
320         /// <param name="propertyNames">实体属性名称数组</param>
321         /// <returns></returns>
322         public int Delete(IEntity entity, string[] propertyNames)
323         {
324             IDataParameter[] param = null;
325             string sql = Factory.CreateDeleteSql(entity, out param, propertyNames);
326             using (IDbProvider provider = new SqlProvider())
327             {
328                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
329             }
330         }
331 
332         /// <summary>
333         /// 根据泛型类删除数据
334         /// 该方法是根据实体的主键删除的
335         /// </summary>
336         /// <typeparam name="T">泛型类</typeparam>
337         /// <param name="t">泛型实例</param>
338         /// <returns></returns>
339         public int Delete<T>(T t) where T : class
340         {
341             IDataParameter[] param = null;
342             string sql = Factory.CreateDeleteSql(typeof(T), t, out param);
343             using (IDbProvider provider = new SqlProvider())
344             {
345                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
346             }
347         }
348 
349         /// <summary>
350         /// 根据泛型类的某个属性删除数据
351         /// 泛型类中必须存在该属性,而且
352         /// 属性值不能为空
353         /// </summary>
354         /// <typeparam name="T">泛型类型</typeparam>
355         /// <param name="t">泛型类实例</param>
356         /// <param name="propertyName">属性名称</param>
357         /// <returns></returns>
358         public int Delete<T>(T t, string propertyName) where T : class
359         {
360             IDataParameter[] param = null;
361             string sql = Factory.CreateDeleteSql(typeof(T), t, out param,propertyName);
362             using (IDbProvider provider = new SqlProvider())
363             {
364                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
365             }
366         }
367 
368         /// <summary>
369         /// 根据泛型类型的多个属性删除数据
370         /// 泛型类型中必须存在这些属性,传
371         /// 递参数的时候不能为null
372         /// </summary>
373         /// <typeparam name="T">泛型类</typeparam>
374         /// <param name="t">泛型实例</param>
375         /// <param name="propertyNames">属性名称数组</param>
376         /// <returns></returns>
377         public int Delete<T>(T t, string[] propertyNames) where T : class
378         {
379             IDataParameter[] param = null;
380             string sql = Factory.CreateDeleteSql(typeof(T), t, out param, propertyNames);
381             using (IDbProvider provider = new SqlProvider())
382             {
383                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
384             }
385         }
386 
387         /// <summary>
388         /// 根据实体的类型删除数据。
389         /// value 中的类型由type确定
390         /// </summary>
391         /// <param name="type">实体类型</param>
392         /// <param name="value">实体对象实例</param>
393         /// <returns></returns>
394         public int Delete(Type type, object value)
395         {
396             IDataParameter[] param = null;
397             string sql = Factory.CreateDeleteSql(type,value,out param);
398             using (IDbProvider provider = new SqlProvider())
399             {
400                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
401             }
402         }
403 
404         /// <summary>
405         /// 根据实体的类型的某个属性删除数据。
406         /// value 中的类型由type确定
407         /// propertyName 属性名称必须在value 
408         /// 对象中存在
409         /// </summary>
410         /// <param name="type">实体类型</param>
411         /// <param name="value">实体对象实例</param>
412         /// <param name="propertyName">属性名称</param>
413         /// <returns></returns>
414         public int Delete(Type type, object value, string propertyName)
415         {
416             IDataParameter[] param = null;
417             string sql = Factory.CreateDeleteSql(type, value, out param,propertyName);
418             using (IDbProvider provider = new SqlProvider())
419             {
420                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
421             }
422         }
423 
424         /// <summary>
425         /// 根据实体的类型的某个属性删除数据。
426         /// value 中的类型由type确定
427         /// propertyName 属性名称必须在value 
428         /// 对象中存在
429         /// </summary>
430         /// <param name="type">实体类型</param>
431         /// <param name="value">实体对象实例</param>
432         /// <param name="propertyNames">属性名称数组</param>
433         /// <returns></returns>
434         public int Delete(Type type, object value, string[] propertyNames)
435         {
436             IDataParameter[] param = null;
437             string sql = Factory.CreateDeleteSql(type, value, out param, propertyNames);
438             using (IDbProvider provider = new SqlProvider())
439             {
440                 return BaseHelper.ExecuteNonQuery(provider, sql, param);
441             }
442         }
443 
444         /// <summary>
445         /// 根据主键查询实体对象
446         /// </summary>
447         /// <typeparam name="T">泛型类型</typeparam>
448         /// <param name="pkPropertyValue">主键值</param>
449         /// <returns></returns>
450         public T GetEntity<T>(object pkPropertyValue) where T : class
451         {
452             IDataParameter[] param = null;
453             string sql = Factory.CreateSingleSql(typeof(T), pkPropertyValue, out param);
454             using (IDbProvider provider = new SqlProvider())
455             {
456                 return BaseHelper.ConvertToEntity<T>(BaseHelper.ExecuteDataReader(provider,sql,param));
457             }
458         }
459 
460         /// <summary>
461         /// 根据实体类的类型和主键值查询实体对象
462         /// 使用 type 确定实体,主键确定数据的唯
463         /// 一性
464         /// </summary>
465         /// <param name="type">实体类型</param>
466         /// <param name="pkPropertyValue">主键值</param>
467         /// <returns></returns>
468         public object GetEntity(Type type, object pkPropertyValue)
469         {
470             IDataParameter[] param = null;
471             string sql = Factory.CreateSingleSql(type,pkPropertyValue,out param);
472             using (IDbProvider provider = new SqlProvider())
473             {
474                 return baseHelper.ConvertToEntity(type,BaseHelper.ExecuteDataReader(provider,sql,param));
475             }
476         }
477 
478         /// <summary>
479         /// 根据某个实体的属性来查询实体对象
480         /// 该属性值能确定数据库唯一数据行
481         /// </summary>
482         /// <typeparam name="T">实体泛型类</typeparam>
483         /// <param name="propertyName">属性名称</param>
484         /// <param name="propertyValue">属性值</param>
485         /// <returns></returns>
486         public T GetEntity<T>(string propertyName, object propertyValue) where T : class
487         {
488             IDataParameter[] param = null;
489             string sql = Factory.CreateQueryByPropertySql(typeof(T),propertyName,propertyValue,out param);
490             using (IDbProvider provider = new SqlProvider())
491             {
492                 return BaseHelper.ConvertToEntity<T>(BaseHelper.ExecuteDataReader(provider,sql,param));
493             }
494         }
495 
496         /// <summary>
497         /// 根据某个实体的属性来查询实体对象
498         /// 该属性值能确定数据库唯一数据行
499         /// </summary>
500         /// <param name="type">实体类型</param>
501         /// <param name="propertyName">属性名称</param>
502         /// <param name="propertyValue">属性值</param>
503         /// <returns></returns>
504         public object GetEntity(Type type, string propertyName, object propertyValue)
505         {
506             IDataParameter[] param = null;
507             string sql = Factory.CreateQueryByPropertySql(type, propertyName, propertyValue, out param);
508             using (IDbProvider provider = new SqlProvider())
509             {
510                 return BaseHelper.ConvertToEntity(type,BaseHelper.ExecuteDataReader(provider,sql,param));
511             }
512         }
513 
514         /// <summary>
515         /// 根据某个实体的多个属性来查询实体对象
516         /// </summary>
517         /// <typeparam name="T">泛型类</typeparam>
518         /// <param name="entity">实体公共接口</param>
519         /// <param name="propertyNames">属性名称数组</param>
520         /// <returns></returns>
521         public T GetEntity<T>(IEntity entity, string[] propertyNames) where T : class
522         {
523             IDataParameter[] param = null;
524             string sql = Factory.CreateSingleSql(entity,out param,propertyNames);
525             using (IDbProvider provider = new SqlProvider())
526             {
527                 return BaseHelper.ConvertToEntity<T>(BaseHelper.ExecuteDataReader(provider,sql,param));
528             }
529         }
530 
531         /// <summary>
532         /// 根据某个实体的多个属性来查询实体对象
533         /// 实体根据type类型来确定
534         /// </summary>
535         /// <param name="type">实体类型</param>
536         /// <param name="entity">实体公共接口</param>
537         /// <param name="propertyNames">属性名称数组</param>
538         /// <returns></returns>
539         public object GetEntity(Type type, IEntity entity, string[] propertyNames)
540         {
541             IDataParameter[] param = null;
542             string sql = Factory.CreateSingleSql(type,entity,out param,propertyNames);
543             using (IDbProvider provider = new SqlProvider())
544             {
545                 return BaseHelper.ConvertToEntity(type,BaseHelper.ExecuteDataReader(provider,sql,param));
546             }
547         }
548         
549 
550         /// <summary>
551         /// 查询该类型实体数据行数
552         /// </summary>
553         /// <param name="type">实体类型</param>
554         /// <returns></returns>
555         public int GetCount(Type type)
556         {
557             string sql = Factory.CreateConverageSql(type,Converage.Count);
558             using (IDbProvider provider = new SqlProvider())
559             {
560                 return (int)BaseHelper.ExecuteScalar(provider,sql);
561             }
562         }
563 
564         /// <summary>
565         /// 查询该类型实体数据行数
566         /// </summary>
567         /// <typeparam name="T">泛型类型</typeparam>
568         /// <returns></returns>
569         public int GetCount<T>() where T : class
570         {
571             string sql = Factory.CreateConverageSql(typeof(T), Converage.Count);
572             using (IDbProvider provider = new SqlProvider())
573             {
574                 return (int)BaseHelper.ExecuteScalar(provider, sql);
575             }
576         }
577 
578         /// <summary>
579         /// 根据条件查询实体数据行数
580         /// </summary>
581         /// <param name="type">实体类型</param>
582         /// <param name="dic">实体属性键值对</param>
583         /// <param name="component">查询组件</param>
584         /// <returns></returns>
585         public int GetCount(Type type, IDictionary<stringobject> dic, ConditionComponent component)
586         {
587             IDataParameter[] param = null;
588             string sql = Factory.CreateConverageSql(type,Converage.Count,"",dic,out param,component);
589             using (IDbProvider provider = new SqlProvider())
590             {
591                 return (int)BaseHelper.ExecuteScalar(provider, sql, param);
592             }
593         }
594 
595         /// <summary>
596         /// 查询所有实体集合
597         /// </summary>
598         /// <typeparam name="T">泛型类型</typeparam>
599         /// <returns></returns>
600         public IList<T> GetList<T>() where T : class
601         {
602             string sql = Factory.CreateQuerySql(typeof(T));
603             using (IDbProvider provider = new SqlProvider())
604             {
605                 return BaseHelper.ConvertToList<T>(BaseHelper.ExecuteDataReader(provider,sql));
606             }
607         }
608 
609         /// <summary>
610         /// 根据某个实体属性查询实体集合
611         /// </summary>
612         /// <typeparam name="T">泛型类型</typeparam>
613         /// <param name="propertyName">属性名称</param>
614         /// <param name="value">属性值</param>
615         /// <returns></returns>
616         public IList<T> GetList<T>(string propertyName, object value) where T : class
617         {
618             IDataParameter[] param = null;
619             string sql = Factory.CreateQueryByPropertySql(typeof(T),propertyName,value,out param);
620             using (IDbProvider provider = new SqlProvider())
621             {
622                 return BaseHelper.ConvertToList<T>(BaseHelper.ExecuteDataReader(provider, sql,param));
623             }
624         }
625 
626 
627         /// <summary>
628         /// 根据多个属性查询实体集合
629         /// </summary>
630         /// <typeparam name="T">泛型类型</typeparam>
631         /// <param name="entity">实体公共接口</param>
632         /// <param name="propertyNames">属性名称</param>
633         /// <returns></returns>
634         public IList<T> GetList<T>(IDictionary<string,object> dic) where T : class
635         {
636             IDataParameter[] param = null;
637             string sql = Factory.CreateQueryByPropertySql(typeof(T), dic, out param);
638             using (IDbProvider provider = new SqlProvider())
639             {
640                 return BaseHelper.ConvertToList<T>(BaseHelper.ExecuteDataReader(provider, sql, param));
641             }
642         }
643 
644         /// <summary>
645         /// 根据多个属性查询实体集合
646         /// 该查询方式附加查询组建
647         /// </summary>
648         /// <typeparam name="T">类型类</typeparam>
649         /// <param name="dic">属性键值对</param>
650         /// <param name="component">查询组件</param>
651         /// <returns></returns>
652         public IList<T> GetList<T>(IDictionary<stringobject> dic, ConditionComponent component) where T : class
653         {
654             IDataParameter[] param = null;
655             string sql = Factory.CreateQueryByPropertySql(typeof(T),dic,out param,component);
656             using (IDbProvider provider = new SqlProvider())
657             {
658                 return BaseHelper.ConvertToList<T>(BaseHelper.ExecuteDataReader(provider, sql, param));
659             }
660         }
661 
662         /// <summary>
663         /// 释放对象内存
664         /// </summary>
665         public void Dispose()
666         {
667             GC.SuppressFinalize(this);
668         }
669     }
670 }
671 

自定义的数据库操作接口:

自定义操作数据库接口
 1 public interface ITabUserDAL: IDbHelper,IDisposable
 2     {
 3         /// <summary>
 4         /// 用户登录
 5         /// </summary>
 6         /// <param name="name">用户名</param>
 7         /// <param name="pass">用户密码</param>
 8         /// <returns></returns>
 9         TabUser GetUser(string name, string pass);
10     }

 自定义数据库操作类:

自定义数据库操作类
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using CommonData.Data.Core.SQLCore;
 6 using Office.Entity;
 7 
 8 namespace Office.DAL.DAL
 9 {
10     public class TabUserDAL:SqlHelper,ITabUserDAL
11     {
12         /// <summary>
13         /// 用户登录
14         /// </summary>
15         /// <param name="name">用户名</param>
16         /// <param name="pass">用户密码(已经MD5加密)</param>
17         /// <returns></returns>
18         public TabUser GetUser(string name, string pass)
19         {
20             TabUser user = new TabUser();
21             user.UserName = name;
22             user.PassWord = pass;
23             user=GetEntity<TabUser>(user, new string[] { "UserName""PassWord" });
24             return user;
25         }
26     }
27 }
28 

这里的四段代码相信大家都能够明白其结构的定义,一般采用的方式每张表定义一个数据库操作接口和一个实现类,而这个操作接口是继承了公共的数据库操作接口,而且还是使用的泛型类型,使用泛型类型使得数据抽象话,而后面的操作过程刚好有与此泛化过程对应的处理过程,在此就保障了核心的一致,每个自定的数据库操作接口都会去继承公共的数据库操作类和实现自身的接口,因此每个自定的数据库操作类就具有了操作上面定义的操作的所有方法。

  在这儿结构中,感觉这个地方使用的非常秒,定义的公共接口中定义的操作方法几乎能后满足增删改查的要求,因此这样就实现了一个ORM操作数据库的完整功能,我们就可以不需要过多的去关心数据库到底是怎样去处理这些方式,我们的任何操作方式都是以对象的方式来操作,不用关系底层的细节实现。当然,任何一个ORM框架都不是能够替换所有的数据库操作,有些过于复杂的操作还是需要自定义sql语句来处理。我们只需在自定义的数据库操作接口中定义相应的方法即可,毕竟这个ORM映射框架也结合了自定义的处理过程,使得程序更加的灵活,可以从多角度去处理。看到这里,对于一个稍微大型的项目,相对于ADO.NET 操作是不是减少了很多代码。

这个东西毕竟是一个人写的,漏洞肯定也不少,自己也没有那么多的时间去测试,只能慢慢的等以后去修改,性能方面的提交,数据复杂度的处理等等问题,在后期的过程中会逐渐来解决这些问题,并与大家分享。如果大家有任何疑问可以留言,或者好的建议可以随时联系我。

2
0
 
标签:.NET ORM 数据库

.NET技术热门文章

    .NET技术最新文章

      最新新闻

        热门新闻