近日,做一个分布式数据库定时同步的项目,也就是说有多个物理节点上的数据库需要在每天某时来同步表中的数据,对于某个指定节点上的某个表发生的变化(增量)可以通过对该表执行的SqlCommand来记录,当同步过程发生时,需要对其它所有节点上的同名表执行相同的SqlCommand。由于,同步是定时发生的,所以增量SqlCommand就需要首先被保存起来,开始我们计划将其序列化后保存在数据库中,但是到运行时,问题来了,SqlCommand是不可序列化的!!!所有继承自IDbCommand的类都是不可序列化的,所有继承自IDbParameter的实现类都是不可序列化的。
遇到了这个问题,是我们当初没有料想到的,看来要妥善的解决这个问题,否则,我们的设计和实现不可避免的要进行大量的修改!我们最后采用的解决方案是自己手写一个可以序列化的ESqlCommand,它可以和SqlCommand相互转换,就像这样:
下面给出ESqlCommand的实现(当然,不可避免的也要包含可序列化的ESqlParameter实现):
遇到了这个问题,是我们当初没有料想到的,看来要妥善的解决这个问题,否则,我们的设计和实现不可避免的要进行大量的修改!我们最后采用的解决方案是自己手写一个可以序列化的ESqlCommand,它可以和SqlCommand相互转换,就像这样:
SqlCommandcommand=newSqlCommand(this.cmdText,newSqlConnection(connStr),null);
//正向
ESqlCommandesCommand=newESqlCommand(command);
//反向
SqlCommandcommand2=esCommand.ToSqlCommand(connStr);
有了ESqlCommand之后,我们的设计几乎不需要修改,仅仅在增量序列化保存到数据库之前转换为ESqlCommand,而读出增量字段反序列化之后再转换为SqlCommand即可。//正向
ESqlCommandesCommand=newESqlCommand(command);
//反向
SqlCommandcommand2=esCommand.ToSqlCommand(connStr);
下面给出ESqlCommand的实现(当然,不可避免的也要包含可序列化的ESqlParameter实现):
#regionESqlCommand
///<summary>
///ESqlCommand可序列化的SqlCommand。System.Data.SqlClient.SqlCommand是不可序列化的
///</summary>
[Serializable]
publicclassESqlCommand
{
privateESqlParameter[]esParas;
privatestringcmdText;
privateCommandTypecmdType;
publicESqlCommand(SqlCommandcommand)
{
this.cmdText=command.CommandText;
this.cmdType=command.CommandType;
this.esParas=newESqlParameter[command.Parameters.Count];
intindex=0;
foreach(SqlParameterparaincommand.Parameters)
{
this.esParas[index]=newESqlParameter(para);
index++;
}
}
publicSqlCommandToSqlCommand(stringconnStr)
{
SqlCommandcommand=newSqlCommand(this.cmdText,newSqlConnection(connStr),null);
for(inti=0;i<this.esParas.Length;i++)
{
command.Parameters.Add(this.esParas[i].ToSqlParameter());
}
command.CommandType=this.cmdType;
returncommand;
}
}
[Serializable]
publicclassESqlParameter
{
publicESqlParameter(SqlParametersPara)
{
this.paraName=sPara.ParameterName;
this.paraLen=sPara.Size;
this.paraVal=sPara.Value;
this.sqlDbType=sPara.SqlDbType;
}
publicSqlParameterToSqlParameter()
{
SqlParameterpara=newSqlParameter(this.paraName,this.sqlDbType,this.paraLen);
para.Value=this.paraVal;
returnpara;
}
#regionParaName
privatestringparaName="";
publicstringParaName
{
get
{
returnthis.paraName;
}
set
{
this.paraName=value;
}
}
#endregion
#regionParaLen
privateintparaLen=0;
publicintParaLen
{
get
{
returnthis.paraLen;
}
set
{
this.paraLen=value;
}
}
#endregion
#regionParaVal
privateobjectparaVal=null;
publicobjectParaVal
{
get
{
returnthis.paraVal;
}
set
{
this.paraVal=value;
}
}
#endregion
#regionSqlDbType
privateSqlDbTypesqlDbType=SqlDbType.NVarChar;
publicSqlDbTypeSqlDbType
{
get
{
returnthis.sqlDbType;
}
set
{
this.sqlDbType=value;
}
}
#endregion
}
#endregion
///<summary>
///ESqlCommand可序列化的SqlCommand。System.Data.SqlClient.SqlCommand是不可序列化的
///</summary>
[Serializable]
publicclassESqlCommand
{
privateESqlParameter[]esParas;
privatestringcmdText;
privateCommandTypecmdType;
publicESqlCommand(SqlCommandcommand)
{
this.cmdText=command.CommandText;
this.cmdType=command.CommandType;
this.esParas=newESqlParameter[command.Parameters.Count];
intindex=0;
foreach(SqlParameterparaincommand.Parameters)
{
this.esParas[index]=newESqlParameter(para);
index++;
}
}
publicSqlCommandToSqlCommand(stringconnStr)
{
SqlCommandcommand=newSqlCommand(this.cmdText,newSqlConnection(connStr),null);
for(inti=0;i<this.esParas.Length;i++)
{
command.Parameters.Add(this.esParas[i].ToSqlParameter());
}
command.CommandType=this.cmdType;
returncommand;
}
}
[Serializable]
publicclassESqlParameter
{
publicESqlParameter(SqlParametersPara)
{
this.paraName=sPara.ParameterName;
this.paraLen=sPara.Size;
this.paraVal=sPara.Value;
this.sqlDbType=sPara.SqlDbType;
}
publicSqlParameterToSqlParameter()
{
SqlParameterpara=newSqlParameter(this.paraName,this.sqlDbType,this.paraLen);
para.Value=this.paraVal;
returnpara;
}
#regionParaName
privatestringparaName="";
publicstringParaName
{
get
{
returnthis.paraName;
}
set
{
this.paraName=value;
}
}
#endregion
#regionParaLen
privateintparaLen=0;
publicintParaLen
{
get
{
returnthis.paraLen;
}
set
{
this.paraLen=value;
}
}
#endregion
#regionParaVal
privateobjectparaVal=null;
publicobjectParaVal
{
get
{
returnthis.paraVal;
}
set
{
this.paraVal=value;
}
}
#endregion
#regionSqlDbType
privateSqlDbTypesqlDbType=SqlDbType.NVarChar;
publicSqlDbTypeSqlDbType
{
get
{
returnthis.sqlDbType;
}
set
{
this.sqlDbType=value;
}
}
#endregion
}
#endregion
1万+

被折叠的 条评论
为什么被折叠?



