使用NHibernate中的拦截器(续)

我的前一篇随笔 《使用NHibernate中的拦截器》中简单讲述了如何使用接口IInterceptor拦截CRUD操作。但没有区分开新增和修改操作。
对于public bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)会在Insert new object之前触发,而public void PreFlush(System.Collections.ICollection entities)则是Update old Object之前和Insert New Object之后都会触发的。为了记录下来明确的实体的insert和update操作,需要将其区分开。所以我查看了NHIbernate的源码,发现Insert  new object到了调用PreFlush后,其ID字段(属性)就有值了,而在OnSave时是为0或者null或者其它配置文件中定义的unsaved-value。通常为了简单,都是使用子动增长的字段作为ID的。所以我写了下面的代码来分别记录“新增”和“修改”的操作:
ExpandedBlockStart.gif ContractedBlock.gif      /**/ /// <summary>
InBlock.gif    
/// CRUD日志记录类
ExpandedBlockEnd.gif    
/// </summary>

None.gif      public   class  LogInterceptor : IInterceptor
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif                
InBlock.gif        
private Hashtable _entity = null;
InBlock.gif        
private Type _entityType = null;
InBlock.gif        
private IEntityManager manager = null;
InBlock.gif        
public LogInterceptor()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            manager 
= EntityManager.CreateEntityManager();
ExpandedSubBlockEnd.gif        }

ContractedSubBlock.gifExpandedSubBlockStart.gif        
IInterceptor 成员#region IInterceptor 成员
InBlock.gif
InBlock.gif                  
//省略其他必须实现的方法dot.gif
InBlock.gif
        public bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// Insert New Object之前会触发
InBlock.gif
            if ( manager.Factory != null )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this._entityType = entity.GetType();
InBlock.gif                
this._entity = Copy(state,propertyNames);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this._entity = null;
InBlock.gif                
this._entityType = null;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
this.AddLog(entity,id,state,propertyNames,"新增"); 
InBlock.gif            
return false;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void OnDelete(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.AddLog(entity,id,state,propertyNames,"删除");
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void PreFlush(System.Collections.ICollection entities)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// Update old Object之前会触发
InBlock.gif            
// Insert New Object之后会触发
InBlock.gif
            if ( entities.Count >0 )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{    
InBlock.gif                
//过滤掉Insert New Object
InBlock.gif
                AddLog(entities,"修改");
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
InBlock.gif        
private Hashtable Copy(object[] state, string[] propertyNames)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            _entity 
= new Hashtable();
InBlock.gif            
for ( int i=0;i<state.Length;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                _entity.Add(propertyNames[i],state[i]);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return _entity;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
private void AddLog(object entity,object entityID,object[] state,string[] propertyNames,string operType)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                                
//如果是日志类自己的话,就不再记录了
InBlock.gif
                if ( entity.GetType() == typeof(DAL.SMS.SM_Log))
InBlock.gif                    
return;
InBlock.gif                Log log 
= Log.CreateLog();
InBlock.gif                StringBuilder states 
= new StringBuilder();
InBlock.gif                
for ( int i=0;i<state.Length;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
if ( state[i] == null )
InBlock.gif                        
continue;
InBlock.gif                    
string pName = propertyNames[i];
InBlock.gif                    
if ( log.dsEntity != null )
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        DataRow[] rows 
= log.dsEntity.Tables[0].Select("Entity='"+entity.ToString()+"' and Property='"+pName+"'");
InBlock.gif                        
if ( rows != null && rows.Length>0 )
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            pName 
= rows[0]["PropertyName"].ToString();
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

InBlock.gif                    states.Append(
"|| "+pName+"--"+state[i].ToString()+" ||\t\r");
ExpandedSubBlockEnd.gif                }

InBlock.gif                log.Add(entity.ToString(),entityID.ToString(),states.ToString(),operType);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{}
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private void AddLog(ICollection entities,string operType)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                IEnumerator e 
= entities.GetEnumerator();
InBlock.gif                
while (e.MoveNext())
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    Type type 
= e.Current.GetType();
InBlock.gif                    
if ( type == typeof(DAL.SMS.SM_Log))
InBlock.gif                        
continue;
InBlock.gif                    PropertyInfo[] pi 
= type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
InBlock.gif                    
string[] propertyNames = new string[pi.Length];
InBlock.gif                    
object[] state = new object[pi.Length];
InBlock.gif                    
object id = e.Current;
InBlock.gif                    
string idName = manager.Factory.GetPersister(type).IdentifierPropertyName;
InBlock.gif                    
if (this._entityType != null && type == _entityType)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
bool isNewObject = true;
InBlock.gif                        
for (int i=0;i<pi.Length;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            
if ( pi[i].Name != idName)
ExpandedSubBlockStart.gifContractedSubBlock.gif                            
dot.gif{
InBlock.gif                                
object v = pi[i].GetValue(e.Current,null);
InBlock.gif                                isNewObject 
&= (_entity[pi[i].Name].ToString() == v.ToString());
ExpandedSubBlockEnd.gif                            }

ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
if ( isNewObject )
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            
continue;
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
for(int i=0;i<pi.Length;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        propertyNames[i]
= pi[i].Name;
InBlock.gif                        state[i]
= pi[i].GetValue(e.Current,null);
InBlock.gif                        
if ( pi[i].Name == idName )
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            id 
= state[i];
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
this.AddLog(e.Current,id,state,propertyNames,operType);
InBlock.gif                    
this._entity = null;
InBlock.gif                    
this._entityType = null;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{}
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

上面代码中的 private  IEntityManager manager  =   null ;是一个用来管理session的管理器,提供了一个属性public ISessionFactoryImplementor Factory,通过该属性才能方面地得知实体类的ID属性的名字:
None.gif public   sealed   class  EntityManager : IEntityManager
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif   
private static ISessionFactory nSessionFactory = null;
InBlock.gif   
//dot.gif
InBlock.gif
   public ISessionFactoryImplementor Factory
ExpandedSubBlockStart.gifContractedSubBlock.gif   
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
get dot.gif{return nSessionFactory as ISessionFactoryImplementor;}
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

获得ID属性的名字:
None.gif string  idName  =  manager.Factory.GetPersister(type).IdentifierPropertyName;

于是现在可以比较粗略地记录下CRUD操作了……
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值