OleDbDataAdapter.Update возвращает строки, но строки не добавляются в электронную таблицу Excel
Я могу добавлять строки в свою таблицу Excel по одной строке за раз, но это невероятно медленно (1 минута для 400 записей, даже с использованием функции Prepare). Итак, я знаю, что Sql действителен и DataTable хорош.
Код, который работает:
public void InsertFromDataTable(string strSql, DataTable dtTable, string strTableName)
{
if (m_oleDbHandler == null)
{
m_oleDbHandler = new OleDbHandler(m_strConnection);
}
//Do one row at a time since the DataAdapter did not work
foreach (DataRow drRow in dtTable.Rows)
{
OleDbParmCollection cololedbParameters = new OleDbParmCollection();
foreach (DataColumn dcColumn in dtTable.Columns)
{
OleDbParameter odpParameter = new OleDbParameter("@" + dcColumn.ColumnName, drRow[dcColumn.ColumnName]);
odpParameter.ParameterName = "@" + dcColumn.ColumnName;
odpParameter.DbType = OleDbHandler.GetDbType(dcColumn.GetType());
odpParameter.Size = dcColumn.MaxLength;
odpParameter.SourceColumn = dcColumn.ColumnName;
cololedbParameters.Add(odpParameter);
}
m_oleDbHandler.ExecuteCommand(strSql, cololedbParameters, true);
}
}
}
Когда я пытаюсь сделать то же самое, используя DataAdapter, он говорит, что возвращает 458 строк, но в электронной таблице нет новых строк. Код, который не работает:
//DataAdapter version
OleDbParmCollection cololedbParameters = new OleDbParmCollection();
foreach (DataColumn dcColumn in dtTable.Columns)
{
OleDbParameter odpParameter = new OleDbParameter();
odpParameter.ParameterName = "@" + dcColumn.ColumnName;
odpParameter.OleDbType = OleDbHandler.GetOleDbType(dcColumn.GetType());
odpParameter.DbType = OleDbHandler.GetDbType(dcColumn.GetType());
odpParameter.Size = dcColumn.MaxLength;
odpParameter.SourceColumn = dcColumn.ColumnName;
cololedbParameters.Add(odpParameter);
}
m_oleDbHandler.InsertFromDataTable(strSql, dtTable, cololedbParameters, strTableName);
а потом:
public int InsertFromDataTable(string strSql, DataTable dtTable, OleDbParmCollection cololeDbParameters, string strTableName)
{
//Set every row as added so that they will be inserted
foreach (DataRow drRow in dtTable.Rows)
{
drRow.SetAdded();
}
//Update the output table
int intRows = -1;
try
{
OleDbCommand oleDbCommand = new OleDbCommand(strSql, OpenConnection());
foreach (OleDbParameter oleDbParameter in cololeDbParameters)
{
if (oleDbParameter.Value == null)
{
oleDbCommand.Parameters.Add(oleDbParameter.ParameterName, OleDbType.VarChar).Value = DBNull.Value;
}
else if (string.IsNullOrEmpty(oleDbParameter.Value.ToString()))
{
oleDbCommand.Parameters.Add(oleDbParameter.ParameterName, OleDbType.VarChar).Value = DBNull.Value;
}
else
{
oleDbCommand.Parameters.Add(oleDbParameter);
}
}
OleDbDataAdapter odaAdapter = new OleDbDataAdapter(new OleDbCommand("SELECT * FROM " + strTableName, OpenConnection()));
odaAdapter.InsertCommand = oleDbCommand;
odaAdapter.MissingMappingAction = MissingMappingAction.Passthrough;
odaAdapter.MissingSchemaAction = MissingSchemaAction.Error;
odaAdapter.TableMappings.Add(strTableName, dtTable.TableName);
foreach (DataColumn dcColumn in dtTable.Columns)
{
odaAdapter.TableMappings[0].ColumnMappings.Add(dcColumn.ColumnName, dcColumn.ColumnName);
}
intRows = odaAdapter.Update(dtTable);
}
catch (OleDbException ex)
{
LogStackTrace();
LogToDb.LogException(ex, LogToDb.c_strAppError);
LogToDb.LogMessage("OleDb error", "OleDbHandler.InsertFromDataTable error", strSql, LogToDb.c_intErrorLevelOleDb);
CancelTransactionAndClose();
throw;
}
finally
{
CloseConnection();
}
return (intRows);
}
Почему я получаю intRows = 458, но в файле Excel нет новых строк?
РЕДАКТИРОВАТЬ: Я только что сделал тест, чтобы увидеть, что произойдет, если я экспортирую в Microsoft Access .mdb (вместо Excel), и результаты говорят мне кое-что. Я получаю 458 пустых строк. Итак, я подозреваю, что я получаю 458 пустых строк в Excel. Итак, теперь вопрос в том, почему все строки пустые.
1 ответ
Понял - ошибка была в разделе ниже. Это хорошо работает для ExecuteNonQuery, но паршиво, когда нет данных.
foreach (OleDbParameter oleDbParameter in cololeDbParameters)
{
if (oleDbParameter.Value == null)
{
oleDbCommand.Parameters.Add(oleDbParameter.ParameterName, OleDbType.VarChar).Value = DBNull.Value;
}
else if (string.IsNullOrEmpty(oleDbParameter.Value.ToString()))
{
oleDbCommand.Parameters.Add(oleDbParameter.ParameterName, OleDbType.VarChar).Value = DBNull.Value;
}
else
{
oleDbCommand.Parameters.Add(oleDbParameter);
}
}
Исправленный код, который хорошо работает как с Access, так и с Excel:
foreach (OleDbParameter oleDbParameter in cololeDbParameters)
{
oleDbCommand.Parameters.Add(oleDbParameter);
}
Произошла вторая, менее серьезная ошибка. я использовал
OleDbHandler.GetOleDbType(dcColumn.GetType());
который должен был быть
OleDbHandler.GetOleDbType(dcColumn.DataType);