自己动手写个ORM实现(2)
这里的做法源于手头的一个真实项目,就是数据处理模块应用了企业库,并没有引用诸如nhibernate,ibatis.net之类的orm框架,所以请注意到标题只是写个“orm实现”,目的就是为了对现有整体框架侵入性最小化的前提之下,将一些通用的crud操作封装成类似orm的处理方式。
很多朋友谈了关于重复“造轮子”的看法,大师们的“轮子”为了兼顾框架整体的通用性,不可能针对每个特定项目做处理,个人觉得我们应该从那些作品(诸如nhibernate)领悟他们的设计思想,然后结合工作中的实际情况,先自己动手做一做,从实践中体会,不失为一种好的学习方式。
关于主键是否采用自增方式,这也得看具体应用。毕竟,使用逻辑主键还是业务主键很久以来就存有争议,个人比较倾向于逻辑主键。
最后,自己动手只是学习的手段而不是本文的目的,实现的方法也并不一定适用于所有朋友的实际情况。希望能够”用20%的精力解决80%的问题“,仅此而已
回到正题
在前一节 自己动手写个ORM实现(1) 中,我们定义了实体接口IEntity,实现IEntity的抽象类EntityBase,以及建立实体-表, 属性-字段对应关系的EntityMappingAttribute以及PropertyMappingAttribute. 相应的,我们声明了一个简单的管理IEntity的接口IEntityManage,如下
![](http://222.173.176.83:88/orm/ientitymanager.jpg)
先声明一个EntityManager吧 , 实现IEntityManager
让我们从最简单的Load<T>(int id)方法开始, 它的作用很简单,就是根据传入的id获取单个实体对象.
GetTableName<T>的原型如下
望文生意,由代码可知道我们默认使用实体类名作为对应的数据库表名当EntityMappingAttribute的TableName属性为空的情况下.
在这里我们使用了反射实现其功能,地球人都知道,反射是比较消耗系统资源的,因此我们对上面的这段代码动点小手术.
作用也很简单明了,就是在一个EntityManager实例的作用域内维护对传入需要操作的实体对象的反射信息的缓存
完整的GetTableName<T>方法实现如下
接下来让我们回到Load<T>方法, 7-18行无需赘述,得到sql操作的dataset,在这里我们使用了企业库.
来到第20行
t = GetByDataRow<T>(row);
根据参数的上下文我们可知, 这个方法的作用是根据sql查询得到的一行数据,转换成相应的实体对象实例
GetByDataRow<T>实现如下
首先我们动态创建一个T实例, 然后调用GetMappedProperties<T>()方法获取, 该实体所有标记了PropertyMappingAttribute的Property集合
然后根据sql查询出来结果,对t实例对象赋值返回,GetMappedProperties<T>,GetFieldName方法实现如下
再来到Load<T>方法的第25行
this.SetPersistedStatus<T>(t, true);
SetPersistedStatus<T>方法就是设置我们IEntity接口的IsPersisted属性, 实体对象的持久化状态了.
实现如下
实现方法和单体查询大同小异, 根据查询出的DataSet 结果集,我们把dataSet变量转换成对应的实体集合, GetByDataSet<T>实现如下
到这里,我们EntityManager非常初步的查询功能(不涉及到条件查询,分页操作)就已经实现了,在后面的章节中我们将逐步实现其他功能.
很多朋友谈了关于重复“造轮子”的看法,大师们的“轮子”为了兼顾框架整体的通用性,不可能针对每个特定项目做处理,个人觉得我们应该从那些作品(诸如nhibernate)领悟他们的设计思想,然后结合工作中的实际情况,先自己动手做一做,从实践中体会,不失为一种好的学习方式。
关于主键是否采用自增方式,这也得看具体应用。毕竟,使用逻辑主键还是业务主键很久以来就存有争议,个人比较倾向于逻辑主键。
最后,自己动手只是学习的手段而不是本文的目的,实现的方法也并不一定适用于所有朋友的实际情况。希望能够”用20%的精力解决80%的问题“,仅此而已
回到正题
在前一节 自己动手写个ORM实现(1) 中,我们定义了实体接口IEntity,实现IEntity的抽象类EntityBase,以及建立实体-表, 属性-字段对应关系的EntityMappingAttribute以及PropertyMappingAttribute. 相应的,我们声明了一个简单的管理IEntity的接口IEntityManage,如下
![](http://222.173.176.83:88/orm/ientitymanager.jpg)
先声明一个EntityManager吧 , 实现IEntityManager
让我们从最简单的Load<T>(int id)方法开始, 它的作用很简单,就是根据传入的id获取单个实体对象.
1
public T Load<T>(int id) where T : IEntity
2
{
3
T t = default(T);
4![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
Type type = typeof(T);
6
string tableName = GetTableName<T>();
7
string sql = "SELECT * FROM {0} WHERE [ID] = {1}";
8
sql = string.Format(sql, tableName, id);
9
Database db = DatabaseFactory.CreateDatabase();
10
DbCommand cmd = db.GetSqlStringCommand(sql);
11![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
try
13
{
14
DataSet ds = db.ExecuteDataSet(cmd);
15![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
if (ds != null && ds.Tables[0].Rows.Count == 1)
17
{
18
DataRow row = ds.Tables[0].Rows[0];
19![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
20
t = GetByDataRow<T>(row);
21
if (t != null)
22
{
23
t.ID = id;
24
//Persisted
25
this.SetPersistedStatus<T>(t, true);
26
}
27
}
28
}
29
catch (Exception ex)
30
{
31
///TODO LOG
32
throw ex;
33
}
34![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
35
return t;
36
}
首先,我们根据传入的泛型变量T获取到一个Type对象,调用GetTableName<T>()得到这个实体类型对应的数据表名![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
18
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
20
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
22
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
23
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
24
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
26
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
27
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
28
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
29
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
30
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
31
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
32
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
33
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
34
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
35
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
36
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
GetTableName<T>的原型如下
1
protected string GetTableName<T>() where T : IEntity {
2
Type type = typeof(T);
3
4
string name = type.Name;
5![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
object[] attrs = type.GetCustomAttributes(typeof(EntityMappingAttribute), false);
7
if (attrs.Length > 0)
8
{
9
EntityMappingAttribute attr = attrs[0] as EntityMappingAttribute;
10![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
if (attr != null && !string.IsNullOrEmpty(attr.TableName))
12
{
13
name = attr.TableName;
14
}
15
}
16
17
return name;
18
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
望文生意,由代码可知道我们默认使用实体类名作为对应的数据库表名当EntityMappingAttribute的TableName属性为空的情况下.
在这里我们使用了反射实现其功能,地球人都知道,反射是比较消耗系统资源的,因此我们对上面的这段代码动点小手术.
1
//缓存实体类型对应表名
2
private static readonly Dictionary<Type, string> tnCache = new Dictionary<Type, string>();
3
//缓存实体属型对应的字段名
4
private static readonly Dictionary<PropertyInfo, string> fnCache = new Dictionary<PropertyInfo, string>();
5
//缓存实体类型的属性集合
6
private static readonly Dictionary<Type, List<PropertyInfo>> pCache = new Dictionary<Type, List<PropertyInfo>>();
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
作用也很简单明了,就是在一个EntityManager实例的作用域内维护对传入需要操作的实体对象的反射信息的缓存
完整的GetTableName<T>方法实现如下
1
protected string GetTableName<T>() where T : IEntity
2
{
3
Type type = typeof(T);
4
if (!tnCache.ContainsKey(type))
5
{
6
string name = type.Name;
7![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
object[] attrs = type.GetCustomAttributes(typeof(EntityMappingAttribute), false);
9
if (attrs.Length > 0)
10
{
11
EntityMappingAttribute attr = attrs[0] as EntityMappingAttribute;
12![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
if (attr != null && !string.IsNullOrEmpty(attr.TableName))
14
{
15
name = attr.TableName;
16
}
17
}
18
tnCache.Add(type, name);
19
}
20![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
return tnCache[type];
22
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
18
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
20
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
22
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
接下来让我们回到Load<T>方法, 7-18行无需赘述,得到sql操作的dataset,在这里我们使用了企业库.
来到第20行
t = GetByDataRow<T>(row);
根据参数的上下文我们可知, 这个方法的作用是根据sql查询得到的一行数据,转换成相应的实体对象实例
GetByDataRow<T>实现如下
1
protected T GetByDataRow<T>(DataRow data) where T : IEntity
2
{
3
T t = Activator.CreateInstance<T>();
4
IEnumerable<PropertyInfo> properties = GetMappedProperties<T>();
5![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
foreach (PropertyInfo p in properties)
7
{
8
string fieldName = GetFieldName(p);
9
object value = data[fieldName] == DBNull.Value ? null : data[fieldName];
10
p.SetValue(t, value, null);
11
}
12![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
return t;
14
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
首先我们动态创建一个T实例, 然后调用GetMappedProperties<T>()方法获取, 该实体所有标记了PropertyMappingAttribute的Property集合
然后根据sql查询出来结果,对t实例对象赋值返回,GetMappedProperties<T>,GetFieldName方法实现如下
1
protected IEnumerable<PropertyInfo> GetMappedProperties<T>() where T : IEntity
2
{
3
Type type = typeof(T);
4
if (!pCache.ContainsKey(type))
5
{
6
PropertyInfo[] properties = type.GetProperties();
7
List<PropertyInfo> props = new List<PropertyInfo>();
8![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
foreach (PropertyInfo p in properties)
10
{
11
if (p.Name.ToUpper() == "ID")
12
{
13
props.Add(p);
14
continue;
15
}
16
object[] attrs = p.GetCustomAttributes(typeof(PropertyMappingAttribute), false);
17![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
if (attrs.Length > 0)
19
{
20
PropertyMappingAttribute attr = attrs[0] as PropertyMappingAttribute;
21![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
22
if (attr != null)
23
props.Add(p);
24
}
25
}
26
pCache.Add(type, props);
27
}
28![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
29
return pCache[type];
30
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
20
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
22
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
24
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
25
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
26
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
28
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
29
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
30
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
1
protected string GetFieldName(PropertyInfo property)
2
{
3
if (!fnCache.ContainsKey(property))
4
{
5
string name = property.Name;
6
Type type = property.GetType();
7![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
object[] attrs = type.GetCustomAttributes(typeof(PropertyMappingAttribute), false);
9
if (attrs.Length > 0)
10
{
11
PropertyMappingAttribute attr = attrs[0] as PropertyMappingAttribute;
12![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
if (attr != null && !string.IsNullOrEmpty(attr.FieldName))
14
{
15
name = attr.FieldName;
16
}
17
}
18
fnCache.Add(property, name);
19
}
20![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
return fnCache[property];
22
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
18
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
20
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
22
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
再来到Load<T>方法的第25行
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
实现如下
1
private void SetPersistedStatus<T>(T t, bool persisted) where T : IEntity
2
{
3
PropertyInfo property = typeof(T).GetProperty("IsPersisted");
4
if (property == null)
5
throw new InvalidOperationException("IsPersisted Property not found !");
6
property.SetValue(t, persisted, null);
7![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
//如果传入对象已持久化,则设置初始状态
9
if (persisted)
10
{
11
object raw = t.Clone();
12
PropertyInfo rawProperty = typeof(T).GetProperty("Raw");
13
if (rawProperty != null)
14
{
15
rawProperty.SetValue(t, raw, null);
16
}
17
}
18
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
18
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
第9行, 如果我们设置传入的实体对象状态为已持久化,则把该对象的Raw属性(IEntity类型)设置为初始状态,为了我们后面所要讲的Update方法等操作
至此, 尽管代码比较quick and dirty, 但我们的工作确实起效了, 它可以帮我们查询出想要的东东了.
-------------------------------------------------------------------------------------------------------------------------------------------
完成了单个实体的查询操作, 接下来我们实现集合查询就比较好办了
1
public List<T> LoadAll<T>() where T : IEntity
2
{
3
Type type = typeof(T);
4
string tableName = GetTableName<T>();
5
string sql = "SELECT * FROM {0}";
6
sql = string.Format(sql, tableName);
7
Database db = DatabaseFactory.CreateDatabase();
8
DbCommand cmd = db.GetSqlStringCommand(sql);
9![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
try
11
{
12
DataSet ds = db.ExecuteDataSet(cmd);
13
List<T> list = GetByDataSet<T>(ds);
14![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
return list;
16
}
17
catch (Exception ex)
18
{
19
///TODO: LOG
20
throw ex;
21
}
22
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
19
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
20
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
22
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
实现方法和单体查询大同小异, 根据查询出的DataSet 结果集,我们把dataSet变量转换成对应的实体集合, GetByDataSet<T>实现如下
1
protected List<T> GetByDataSet<T>(DataSet data) where T : IEntity
2
{
3
List<T> list = new List<T>();
4![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
if (data != null && data.Tables[0] != null)
6
{
7
foreach (DataRow row in data.Tables[0].Rows)
8
{
9
T t = GetByDataRow<T>(row);
10
if (t != null)
11
{
12
t.ID = Convert.ToInt32(row["ID"]);
13
list.Add(t);
14
}
15
}
16
}
17![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
return list;
19
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
到这里,我们EntityManager非常初步的查询功能(不涉及到条件查询,分页操作)就已经实现了,在后面的章节中我们将逐步实现其他功能.
posted on 2008-05-26 10:07 yyliuliang 阅读(3796) 评论(10) 编辑 收藏 举报