Я придумала решение, которое позволило мне автоматизировать подход, но в то же время помогло повысить производительность ... Надеюсь, что техника может помочь и другим. Моя проблема была при использовании System.Data (через SqlCE, но применимо и для других баз данных). Каждый раз, когда я пытался создать объект команды SQL для выполнения вставки, обновления или чего-либо еще и добавлять «параметры» в объект sql, получать надлежащие типы данных и т. Д., Это снижало производительность. Итак, я сделал это для вставки / обновления. В моем классе менеджера данных (по одному на таблицу, с которой я работаю) я добавил объекты объектов IDbCommand, по одному для вставки / обновления соответственно. Во время конструктора я предварительно запрашивал таблицу, чтобы получить структуру конечного объекта строки, и предварительно собирал запрос и параметры (пропуская идентификатор первичного ключа) что-то вроде ...
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 таблицы в конце строительного цикла / цикла объекта. Работает отлично. Теперь, если мне когда-либо понадобится развернуть структуру или последовательность столбцов таблицы, мне не нужно менять ЛЮБОЙ код для вставки, процессы обновления.