Фильтрация результатов таблицы SQL на основе коллекции C # - PullRequest
0 голосов
/ 15 июня 2011

У меня есть простая таблица, в которой в основном есть столбец NVARCHAR Name и столбец DateTime Timestamp. Я хочу написать функцию C #, которая принимает коллекцию Names и DateTimes и возвращает все из моей таблицы, где совпадают Names и DateTimes в коллекции старше, чем DateTimes в таблице.

Простой способ, который придумал мой мозг, не относящийся к SQL, - создать инструкцию SELECT, чтобы получить все совпадающие имена («SELECT Name, Timestamp From MyTable WHERE Name IN (...)»), а затем выполнить итерацию по возвращенная коллекция, сравнивающая DateTimes.

Должен быть лучший способ сделать это с помощью SQL или Linq. Как я могу более эффективно сделать это?

UPDATE: Спасибо за полезный отзыв! Похоже, что запуск анализатора запросов на различных подходах, перечисленных здесь, будет подходить. Вот еще один, чтобы выбросить там, если таковые имеются любопытно:

List<Item> items = ... // this the collection
var db = new ItemDataContext(); // From .Net EF

  string[] results = (from item in items
                      from dbItem in db.Items
                      where item.Name.Equals(dbItem.Name,StringComparison.InvariantCultureIgnoreCase)
                            && item.Timestamp < dbItem.Timestamp
                      select dbItem.Token).ToArray();

Ответы [ 4 ]

2 голосов
/ 15 июня 2011

У меня есть запись в блоге о передаче списка идентификаторов здесь: Передача идентификаторов хранимым процессам с использованием XML

Заканчивается в виде:

EXECUTE dbo.getLocationTypes '<IDList><ID>1</ID><ID>3</ID></IDList>', 
'<IDList><ID>200</ID><ID>300</ID><ID>400</ID></IDList>'  
1 голос
/ 15 июня 2011

Если вы используете SQLServer 2008, другой альтернативой может быть передача таблицы данных .net в TSQL. Для получения дополнительной информации: http://www.sommarskog.se/arrays-in-sql-2008.html#DataTable

1 голос
/ 15 июня 2011

Дан список некоторого типа, который содержит строку и дату и время:

public class MyType
{ 
    public Name {get;set;} 
    public Timestamp {get;set;}
}

Результаты поиска SPROC заполняют список myList Вам также предоставляется список строк List myNamesList

var results = myList.Where(r => myNamesList.Contains(r.Name) && myList.Timestamp > someDateTime).ToList();

Результаты в списке отфильтрованных результатов.

1 голос
/ 15 июня 2011

Использование большого списка IN не обязательно плохо, но вы можете столкнуться с проблемами, если у вас есть тысячи элементов в списке, так как указатель параметров может вызвать проблемы.

Но, в принципе, другой подход состоит в том, чтобы присоединиться к некоторой (временной) таблице.Однако использование этой стратегии потребует от вас вставки данных в таблицу, поэтому, если вы не сможете многократно использовать запрос, работа, связанная с вставкой данных фильтра, в значительной степени превысит работу по возвращению результатов.

Лучшим советом здесь, как и везде, будет поиск результатов в анализаторе запросов.

Пример второго подхода с использованием временной таблицы показан ниже.Здесь вы можете получить преимущество от использования индексов в JOIN, но это следует сопоставить со стоимостью вставок для каждого значения фильтра и сложностью в коде, использующем функцию фильтра.(Простое предложение IN автоматически сгенерировано LINQ, в то время как подход к временным таблицам потребует некоторого сокращения в коде.)

   CREATE TABLE vals (v nvarchar(255), inserted DATETIME DEFAULT(getdate()))

   SELECT * FROM vals 
     WHERE v IN ('a', 'aa', 'aaa')

   DECLARE @filters TABLE (v varchar(256))

   INSERT INTO @filters (v) VALUES ('a')
   INSERT INTO @filters (v) VALUES ('aa')
   INSERT INTO @filters (v) VALUES ('aaa')

   SELECT * FROM vals INNER JOIN @filters f
     ON f.v = vals.v
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...