Удалить строки из DataTable, где запись существует в другом DataTable - PullRequest
1 голос
/ 03 ноября 2011

Извините за запутанную строку темы:)

Я хочу сделать SQL-подобный запрос с моей DataTable: s: Я хочу сделать что-то вроде этого

// Is named "BadValues" Rows contain: id1, id2
DataTable tableReadFromFile = readFromFile();
// Is named "AllValues" Rows contain id1, id2
DataTable tableReadFromSql = readFromSql

DataTable resultTable = 
    tableReadFromFile.select("where AllValues.id1 not in (select id1 from BadValues) and AllValues.id2 not in (select id2 from BadValues)");

Так что, если мой "Таблица BadValues ​​"выглядела бы так:

id1 id2
0    1
10   11
20   21

, а моя таблица" AllValues ​​"выглядела бы так:

id1 id2
0   1
0   2
1   1
10  11
10  12
12  11
20  21
20  22
22  21

Я бы хотел, чтобы таблица результатов выглядела так:

id1 id2
0   2
1   1
10  12
12  11
20  22
22  21

Другими словами: если пара id1, id2 существует в таблице "BadValues" и в "AllValues", я хочу удалить их, чтобы они не существовали в таблице результатов.

Это было бы довольно просто сделать в SQL, если бы таблица «BadValues» существовала в базе данных SQL, но поскольку она загружена из файла, который не возможен.

Как сейчас, я перебираю циклвсе строки в «BadValues» и построить отдельные запросы SQL с установленными значениями id1 и id2.Поскольку у меня довольно много данных, это очень много времени.

Любой совет приветствуется!

Ответы [ 3 ]

1 голос
/ 03 ноября 2011

Я думаю, что это сделает это:

DataTable tblBadValues; // filled however
DataTable tblAllValues; // filled however
tblBadValues.Merge(tblAllValues); // this will add to tblBadValues all records 
                                  // that aren't already in there
DataTable tblResults = tblBadValues.getChanges(); // this will get the records
    // that were just added by the merge, meaning it will return all the records
    // that were originally in tblAllValues that weren't also in tblBadValues
tblBadValues.RejectChanges(); // in case you need to re-use tblBadValues
0 голосов
/ 03 ноября 2011

У меня есть идея, хотя вам придется сделать LINQ to SQL.

var query = from data in AllObjects                                    
                    select data;

foreach (DataObject o in BadData)
{
    DataObject temp = o;
    query = query.Where(x => !((x.id1 == temp.id1) && (x.id2 == temp.id2)));
}
//query now contains the expression to get only good rows.

Только когда query повторяется (или .ToArray и т. Д.), Он выполняет вызов к вашему серверу базы данных.

0 голосов
/ 03 ноября 2011

Использование Linq для набора данных :

var badValues = new HashSet<Tuple<int, int>>(
                  tableReadFromFile.AsEnumerable().
                                    Select(row => 
                                      new Tuple<int, int>(row.Field<int>("id1"), row.Field<int>("id2"))));

var result = tableReadFromSql.AsEnumerable().
                                    Where(row => !(badValues.Contains(
                                    new Tuple<int, int>(row.Field<int>("id1"), row.Field<int>("id2")))));

Первое утверждение в основном создает хэш-набор кортежей, представляющих неверные значения.

Вторая ищет во второй таблице строки, идентификаторы которых отсутствуют в хэш-наборе.

...