我想出了一个解决方案,它允许我采用自动化方法,同时帮助提高性能......希望该技术也可以帮助其他人。我的问题是在使用 System.Data 时(通过 SqlCE,但也适用于其他数据库后端)。每次我尝试创建 SQL 命令对象来执行插入、更新或其他操作,并将“参数”添加到 sql 对象、获取正确的数据类型等时,都会降低性能。所以,我为插入/更新做了这个。在我的数据管理器类(我使用的每个表一个)上,我添加了 IDbCommand 对象的对象,一个分别用于插入/更新。在构造函数期间,我会预先查询表以获取最终行对象的结构,并预先构建查询和参数(跳过主键 ID),例如...
private void BuildDefaultSQLInsert()
{
// get instance to the object ONCE up front
// This is a private property on the data manager class of IDbCommand type
oSQLInsert = GetSQLCommand("");
// pre-build respective insert statement and parameters ONCE.
// This way, when actually called, the object and their expected
// parameter objects already in place. We just need to update
// the "Value" inside the parameter
String SQLCommand = "INSERT INTO MySQLTable ( ";
String InsertValues = "";
// Now, build a string of the "insert" values to be paired, so
// add appropriate columns to the string, and IMMEDIATELY add their
// respective "Value" as a parameter
DataTable MyTable = GetFromSQL( "Select * from MySQLTable where MyIDColumn = -1" );
foreach (DataColumn oCol in MyTable.Columns)
{
// only add columns that ARE NOT The primary ID column
if (!(oCol.ColumnName.ToUpper() == "MYIDCOLUMN" ))
{
// add all other columns comma seperated...
SQLCommand += oCol.ColumnName + ",";
InsertValues += "?,";
// Ensure a place-holder for the parameters so they stay in synch
// with the string. My AddDbParm() function would create the DbParameter
// by the given column name and default value as previously detected
// based on String, Int, DateTime, etc...
oSQLInsert.Parameters.Add(AddDbParm(oCol.ColumnName, oCol.DefaultValue));
}
}
// Strip the trailing comma from each element... command text, and its insert values
SQLCommand = SQLCommand.Substring(0, SQLCommand.Length - 1);
InsertValues = InsertValues.Substring(0, InsertValues.Length - 1);
// Now, close the command text with ") VALUES ( "
// and add the INSERT VALUES element parms
SQLCommand += " ) values ( " + InsertValues + " )";
// Update the final command text to the SQLInsert object
// and we're done with the prep ONCE
oSQLInsert.CommandText = SQLCommand;
}
接下来,当我需要实际执行所有记录的插入操作时,我通过我的 Add() 函数执行此操作,并传入我正在处理的 DataRow 的一个实例。由于 SQLInsert 对象已经使用相应的参数构建,因此我可以循环浏览与数据管理器负责的相同类型的数据行,并使用数据行的当前“值”更新参数对象
public Boolean AddMyRecord(DataRow oDR)
{
// the parameter name was set based on the name of the column,
// so I KNOW there will be a match, and same data type
foreach (IDbDataParameter oDBP in oSQLInsert.Parameters)
oDBP.Value = oDR[oDBP.ParameterName];
ExecuteMySQLCommand( oSQLInsert );
}
通过针对手持设备的一些定时试验,运行/验证大约 20 个查询和 10 个插入的前后时间从大约 10 秒缩短到 2.5 秒。该技术与执行 SQLUpdate 的技术类似,但在构建字符串/对象循环结束时将 WHERE 子句强制用于表的主 ID 列。它工作得很好。现在,如果我需要扩展表的结构或列序列,我不必更改插入、更新过程的任何代码。