Добавление дублей из таблицы (вложенный цикл for) DataTable
Нужно чтобы этот алгоритм добавил те строки, которых нет в DataTable globalDataMySQL из таблицы DataTable globalDataExcel. В данный момент добавляет строки и которые есть и которых нет. Пример приложил на скриншотах.
Код:
for (int i = 0; i < globalDataTableMySQL.Rows.Count; ++i)
{
if (globalDataTableMySQL.Rows[i].RowState != DataRowState.Deleted)
{
for (int j = 0; j < globalDataTableExcel.Rows.Count; ++j)
{
bool found = false;
if (globalDataTableMySQL.Rows[j][0].ToString() == globalDataTableExcel.Rows[i][0].ToString())
{
found = true;
break;
}
if (!found)
{
globalDataTableMySQL.Rows.Add(globalDataTableExcel.Rows[i][0].ToString());
++plusSlov;
break;
}
}
}
}
Результат нажатия кнопки (приведение в действие алгоритма)

Ответы (3 шт):
Решение. Пока работает корректно, не знаю как, но работает
for (int i = 0; i < globalDataTableExcel.Rows.Count; ++i)
{
if (globalDataTableExcel.Rows[i].RowState != DataRowState.Deleted)
{
bool found = false;
for (int j = 0; j < globalDataTableMySQL.Rows.Count; ++j)
{
if (globalDataTableExcel.Rows[i][0].ToString() == globalDataTableMySQL.Rows[j][0].ToString())
{
found = true;
break;
}
}
if (!found)
{
globalDataTableMySQL.Rows.Add(globalDataTableExcel.Rows[i][0].ToString());
++plusSlov;
}
}
}
В вашем коде есть ряд ошибок ошибок. Указывать на каждую ошибку - достаточно долго. Если кратко - основные моменты:
if (!found)конструкция должна быть за пределами внутреннего цикла.Внешний цикл должен быть по
Excel- строкам.В своей версии вы запутались в индексах
iиj. Например, в строке кода:if (globalDataTableExcel.Rows[i][0].ToString() == globalDataTableMySQL.Rows[j][0].ToString())У вас ошибка. Индекс
i- это индекс поMySqlстрокам, аj- поExcel
Я предпочел уйти от индексов и использовать foreach. Моя версия итогового варианта:
foreach (DataRow excelRow in globalDataTableExcel.Rows)
{
bool found = false;
foreach (DataRow sqlRow in globalDataTableMySQL.Rows)
{
if (sqlRow.RowState != DataRowState.Deleted && // Не знаю, для чего вы добавили условие на Deleted, я его оставил
sqlRow[0].ToString() == excelRow[0].ToString())
{
found = true;
break;
}
}
if (!found)
{
var newSqlRow = globalDataTableMySQL.NewRow();
newSqlRow[0] = excelRow[0];
globalDataTableMySQL.Rows.Add(newSqlRow);
}
}
Решение на LINQ
globalDataTableExcel.Rows
.Cast<DataRow>()
.Where(x => globalDataTableMySQL.Rows
.Cast<DataRow>()
.Any(y => (int)y["num"] != (int)x["num"]))
.ToList()
.ForEach(x => globalDataTableMySQL.Rows.Add(x["num"]));
Если у вас будет строка из 20 колонок, вы заколебетесь с индексами... Используйте ассоциативный индекс Row[ColumnName], не нужно будет каждый раз вспоминать/перепроверять у какой колонки какой номер, тем более порядок столбцов в БД может быть изменен.
Вы используйте устаревший подход работы с БД. В .NET есть LINQ и Entity Framework, которые намного упрощают жизнь, обязательно посмотрите их.
Данные, с которыми работал
#region Подготовка данных
string[] names =
{
"Тестировщиков Тест Тестович",
"Безопасников Безопас Безопасникович",
"Заказчиков Заказ Заказович",
};
// globalDataTableMySQL.
DataTable globalDataTableExcel = new DataTable();
globalDataTableExcel.Columns.Add("num", typeof(int));
globalDataTableExcel.Columns.Add("name", typeof(string));
for (int i = 0; i < names.Length; i++)
{
DataRow row = globalDataTableExcel.NewRow();
row["num"] = i;
row["name"] = names[i];
globalDataTableExcel.Rows.Add(row);
}
// globalDataTableMySQL.
DataTable globalDataTableMySQL = new DataTable();
globalDataTableMySQL.Columns.Add("num", typeof(int));
DataRow sqlRow = globalDataTableMySQL.NewRow();
sqlRow["num"] = 1;
globalDataTableMySQL.Rows.Add(sqlRow);
#endregion

