Выберите строки из одной таблицы данных, а не из другой - PullRequest
1 голос
/ 18 января 2012

Я пытаюсь получить список строк в DataTableA, где значение в Column 1 не в Column1 из DataTableB.

Я использую следующий запрос LinQ

//Not in Database
var query = from i in dtImport.AsEnumerable()
            where !dtProducts.AsEnumerable().Any(p => p[colP] == i[colI])
            select i;

Такой, что мне нужен список товаров в таблице импорта, которых еще нет в таблице товаров.

Что, кажется, быстро пропускает строку, когда я отлаживаю, но затем, когда я вызываю что-либо, относящееся к этому запросу, например int rows = query.Count<DataRow>(); или DataTable dtResult = query.CopyToDataTable();, кажется, что это занимает много времени, поэтому я просто останавливаю программу.

Итак, что я делаю не так?

Ответы [ 3 ]

3 голосов
/ 18 января 2012

Ожидается замедление: запрос не будет оценен, пока вы не перечислите результаты, поэтому вы пропускаете эту строку в отладчике довольно быстро: все, что он делает - это готовит запрос к источнику данных;Запросы выполняются при перечислении результатов.

Насколько я могу судить без профилирования вашего кода, проблема, вероятно, связана с большим выбором out-of-db, который происходит при преобразовании dtProducts и *От 1004 * до IEnumerable: по сути, вы переносите данные из обеих таблиц в память перед выбором.Если ваши таблицы имеют значительный размер, это, вероятно, где большую часть времени.Но опять же, единственный верный способ сказать это - профилирование.

2 голосов
/ 18 января 2012

Linq использует отложенное выполнение. Запрос выполняется, когда он используется (не объявлен)
Для повышения производительности вы можете использовать HashSet, как показано ниже:

var set = new HashSet<int>(dtProducts.AsEnumerable().Select(p => p.colP));
var result = dtImport.AsEnumerable().Where(i => !set.Contains(i[colI])).ToList();
1 голос
/ 18 января 2012

Ваш запрос медленный, потому что он должен перечислять продукты для каждой записи в dtImport. Сначала поместите продукты в словарь, чтобы ускорить ваш запрос.

var prod = dtProducts.AsEnumerable().ToDictionary(p => p[colP]);  
var query = from imp in dtImport.AsEnumerable()  
            where !prod.ContainsKey(imp[colI])  
            select imp;  
...