分布式数据库定时同步问题之--SqlCommand不可序列化

    近日,做一个分布式数据库定时同步的项目,也就是说有多个物理节点上的数据库需要在每天某时来同步表中的数据,对于某个指定节点上的某个表发生的变化(增量)可以通过对该表执行的SqlCommand来记录,当同步过程发生时,需要对其它所有节点上的同名表执行相同的SqlCommand。由于,同步是定时发生的,所以增量SqlCommand就需要首先被保存起来,开始我们计划将其序列化后保存在数据库中,但是到运行时,问题来了,SqlCommand是不可序列化的!!!所有继承自IDbCommand的类都是不可序列化的,所有继承自IDbParameter的实现类都是不可序列化的。
    遇到了这个问题,是我们当初没有料想到的,看来要妥善的解决这个问题,否则,我们的设计和实现不可避免的要进行大量的修改!我们最后采用的解决方案是自己手写一个可以序列化的ESqlCommand,它可以和SqlCommand相互转换,就像这样:

            SqlCommand command  =   new  SqlCommand( this .cmdText , new  SqlConnection(connStr) , null ) ;
            
// 正向
            ESqlCommand esCommand  =   new  ESqlCommand(command) ;
            
// 反向
            SqlCommand command2  =  esCommand.ToSqlCommand(connStr) ;

    有了ESqlCommand之后,我们的设计几乎不需要修改,仅仅在增量序列化保存到数据库之前转换为ESqlCommand,而读出增量字段反序列化之后再转换为SqlCommand即可。
    下面给出ESqlCommand的实现(当然,不可避免的也要包含可序列化的ESqlParameter实现):

    #region  ESqlCommand
    
///   <summary>
    
///  ESqlCommand 可序列化的SqlCommand。System.Data.SqlClient.SqlCommand是不可序列化的
    
///   </summary>
    [Serializable]
    
public   class  ESqlCommand
    {
        
private  ESqlParameter[] esParas ;
        
private   string           cmdText ;
        
private  CommandType     cmdType ;

        
public  ESqlCommand(SqlCommand command)
        {
            
this .cmdText  =  command.CommandText ;
            
this .cmdType  =  command.CommandType ;

            
this .esParas  =   new  ESqlParameter[command.Parameters.Count] ;
            
int  index  =   0  ;
            
foreach (SqlParameter para  in  command.Parameters)
            {
                
this .esParas[index]  =   new  ESqlParameter(para) ;
                index
++  ;
            }
        }

        
public  SqlCommand ToSqlCommand( string  connStr)
        {
            SqlCommand command 
=   new  SqlCommand( this .cmdText , new  SqlConnection(connStr) , null ) ;
          

            
for ( int  i = 0  ;i < this .esParas.Length ;i ++ )
            {
                command.Parameters.Add(
this .esParas[i].ToSqlParameter()) ;
            }        
            
            command.CommandType 
=   this .cmdType ;
            
return  command ;            
        }
    }

    [Serializable]
    
public   class  ESqlParameter
    {
        
public  ESqlParameter(SqlParameter sPara)
        {
            
this .paraName  =  sPara.ParameterName ;
            
this .paraLen   =  sPara.Size ;
            
this .paraVal   =  sPara.Value ;
            
this .sqlDbType =  sPara.SqlDbType ;        
        }

        
public  SqlParameter ToSqlParameter()
        {
            SqlParameter para 
=   new  SqlParameter( this .paraName , this .sqlDbType , this .paraLen) ;
            para.Value 
=   this .paraVal ;

            
return  para ;
        }


        
#region  ParaName
        
private   string  paraName  =   ""  ; 
        
public   string  ParaName
        {
            
get
            {
                
return   this .paraName ;
            }
            
set
            {
                
this .paraName  =  value ;
            }
        }
        
#endregion
    
        
#region  ParaLen
        
private   int  paraLen  =   0  ; 
        
public   int  ParaLen
        {
            
get
            {
                
return   this .paraLen ;
            }
            
set
            {
                
this .paraLen  =  value ;
            }
        }
        
#endregion
    
        
#region  ParaVal
        
private   object  paraVal  =   null  ; 
        
public   object  ParaVal
        {
            
get
            {
                
return   this .paraVal ;
            }
            
set
            {
                
this .paraVal  =  value ;
            }
        }
        
#endregion         

        
#region  SqlDbType
        
private  SqlDbType sqlDbType  =  SqlDbType.NVarChar ; 
        
public  SqlDbType SqlDbType
        {
            
get
            {
                
return   this .sqlDbType ;
            }
            
set
            {
                
this .sqlDbType  =  value ;
            }
        }
        
#endregion

    }
    
#endregion

 

你可能感兴趣的:(command)