动态获取Nhibernate的ORM配置信息,实现系统历史记录功能

1

问题场景

         系统的数据层采用 Spring.net  框架。

项目对数据的要求

1每一个业务表的业务信息只能注销,不能物理删除(也就是我们经常说的保存历史数据)

2)不能将表的失效信息暴露在实体类中

 

2 解决流程

  解决的流程

  Step one  通过Session中的SessionFactory 查找到业务实体类的ORM信息

           在这里,我们最关注ORM信息中的有两点

1)   业务实体类  -------- 数据库中表

2)   业务实体类的主键属性 ---数据库中列信息

 

 补充说明:

          在这边我们支持类的映射信息配置的主键主要包含了三个组成方式

        1 类的主键类型为复合主键且子主键为key-property

        2 类的主键类型为复合主键且子键中包含了key-property 也包含了key-many-to-one

        3 类的主键类型直接为property

 

Step Two 根据ORM信息取对应数据库中表的列对应的业务实体属性值

        

Step Three  Step Two 提取出来的的信息转化成我们需要数据格式

     属性                       属性说明

TableName                表名

IdentifierColumnNames      主键对应数据库表中的列名

identifierValues             业务实体中的主键属性值

KeyNum                     主键的列数目

 

Step Four  根据 step three 的信息拼装SQL语句并执行

 

 

3类的设计

 

Nhibernate.jpg

 

                             类图

3.1 ClassMappingInfo

功能说明:存储了类和数据库表之间的NHibernate配置信息

 

属性

属性名

属性含义

属性数据类型

TableName

表名

String

IdentifierColumnNames

主键列名

String[]

IdentifierValues

主键对应的对象属性值

String[]

ColumnLength

主键列的数目

Int

 

3.2 ClassMappingInfoBuilder

功能说明:

   根据类和Isession来获取ClassMappingInfo

函数

   public ClassMappingInfo Get(object obj, ISession session)

   参数

      Obj :数据持久类

      SessionNHibernate Session实例

   返回类型  ClassMappingInfo

 

 

 

3.3 DeleteCommandCreater

功能说明:

   根据ClassMappingInfo 映射信息,来生成删除功能的sql语句

函数

   public override string GetSqlCommand()

 

   返回类型 string



 

4 核心代码说明

  下面是核心函数

 参数接口为  业务实体对象的类型,业务实体对象,spring.net 中的Session对象

实现的功能是:

   提取业务实体对象的主键信息(包含实体中主键属性值和数据表中的主键列的信息)

 

 

Code
 1
 2    /**//************************************************************
 3    * this file is part of Platform Project
 4    * Copyright (C)YuChuang Soft 
 5    * 
 6    * Author      :  xwb
 7    * Mail        : 
 8    * Create Date : 2009/1/21
 9    * Summary   : 负责根据类和Nhibernate的Session信息 来获取类的Mapping配置信息
10    * 
11    *  
12    * *************************************************************/

13
14    public class ClassMappingInfoBuilder
15    {
16      
17        /**//// <summary>
18        /// 在获取类的映射信息时主键主要包含了三个组成方式
19        /// 1 类的主键类型为复合主键且子主键为key-property
20        /// 2 类的主键类型为复合主键且子键中包含了key-property 也包含了key-many-to-one
21        /// 3 类的主键类型直接为property
22        /// </summary>
23        /// <param name="obj"></param>
24        /// <param name="session"></param>
25        /// <returns></returns>

26      
27        public ClassMappingInfo Get(Type T, object  obj, ISession session)
28        {
29            //获取映射信息
30            ClassMappingInfo classMappingInfo = new ClassMappingInfo();
31
32            //--取类对应的表名---
33            
34            //注意Nhibernate对我们的持久类封装了一道
35
36            IClassMetadata classMeta = session.SessionFactory.GetClassMetadata(T);
37            classMappingInfo.TableName = ((SingleTableEntityPersister)classMeta).TableName;
38
39            NHibernate.Type.IType IdentifierType = classMeta.IdentifierType;
40            string IdentifierPropertyName= classMeta.IdentifierPropertyName;
41
42
43            object IdentifierInstance = T.GetProperty(IdentifierPropertyName).GetValue(obj,null);
44          
45         
46            //-----取类的主键信息---//
47            
48            //主键 为复合主键
49            Type Type1 = typeof(NHibernate.Type.ComponentType);
50            Type Type2 = IdentifierType.GetType();
51
52            if (Type1.ToString() == Type2.ToString())//为复合主键
53            {
54                // 取每个主键属性。
55                NHibernate.Type.ComponentType currentType = ((NHibernate.Type.ComponentType)IdentifierType);
56                string[] ColumnNames = new string[currentType.PropertyNames.Length];
57                string[] AttributeValues = new string[currentType.PropertyNames.Length];
58
59                for (int index = 0; index < currentType.PropertyNames.Length; index++)
60                {
61
62                    NHibernate.Type.IType subType = currentType.Subtypes[index];
63                    ColumnNames[index]=((SingleTableEntityPersister)classMeta).IdentifierColumnNames[index];
64                    if (subType.IsEntityType)//注意主键是ManyToOne 的方式
65                    {
66                        object subidentifierobj= IdentifierInstance.GetType().GetProperty(currentType.PropertyNames[index]).GetValue(IdentifierInstance, null);
67                        
68                        //递归获取对应的主键子类的Mapping信息
69                        ClassMappingInfo subclassMappinginfo = Get(subType.ReturnedClass, subidentifierobj, session);
70                        AttributeValues[index] = subclassMappinginfo.identifierValues[0]; 
71               
72                    }

73                    else
74                    
75                        AttributeValues[index] =IdentifierInstance.GetType().GetProperty(currentType.PropertyNames[index]).GetValue(IdentifierInstance, null).ToString();                 
76                    }

77
78                }

79                classMappingInfo.IdentifierColumnNames = ColumnNames;
80                classMappingInfo.identifierValues = AttributeValues;
81            }

82            else  //为单一主键
83            {
84                string[] ColumnNames = new string[1];
85                string[] AttributeValues = new string[1];
86                ColumnNames[0= ((SingleTableEntityPersister)classMeta).IdentifierColumnNames[0];
87                AttributeValues[0= IdentifierInstance.ToString();
88                classMappingInfo.IdentifierColumnNames = ColumnNames;
89                classMappingInfo.identifierValues = AttributeValues;
90            }

91
92            return classMappingInfo;
93        }

94    }

95}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值