Я перехожу из ADO.NET в Linq. Приложение представляет собой программу поиска по каталогам для поиска людей. Пользователям разрешено вводить критерии поиска в одно текстовое поле. Они могут отделять каждый термин пробелом или обертывать фразу в кавычки, например «место парковки», чтобы указать, что это один термин.Поиск набора данных с несколькими терминами с использованием Linq
За кулисами данные поступают из файла XML, в котором содержится около 90 000 записей и составляет около 65 мегабайт. Я загружаю данные в DataTable, а затем использую метод .Select с SQL-запросом для выполнения поиска. Запрос, который я передаю, построен из условий поиска, которые пользователь прошел. Я разделил строку из текстового поля на массив, используя регулярное выражение, которое разделит все на отдельный элемент, в котором есть пробел. Однако, если есть цитаты вокруг фразы, это становится ее собственным элементом в массиве. Затем я получаю один размерный массив с числом элементов x, который я перебираю для построения длинного запроса.
Я затем построить выражение поиска ниже:
query = query & _
"((userid LIKE '" & tempstr & "%') OR " & _
"(nickname LIKE '" & tempstr & "%') OR " & _
"(lastname LIKE '" & tempstr & "%') OR " & _
"(firstname LIKE '" & tempstr & "%') OR " & _
"(department LIKE '" & tempstr & "%') OR " & _
"(telephoneNumber LIKE '" & tempstr & "%') OR " & _
"(email LIKE '" & tempstr & "%') OR " & _
"(Office LIKE '" & tempstr & "%'))"
Каждый член будет иметь набор вышеупомянутого запроса. Если существует более одного термина, я помещаю AND между ними и строю другой запрос, как указано выше, со следующим термином. Я не уверен, как это сделать в Linq. До сих пор я правильно загрузил файл XML. Я могу найти его по определенным критериям, но я не уверен, как наилучшим образом реализовать поиск по нескольким терминам.
'this works but far too simple to get the job done
Dim results = From c In m_DataSet...<Users> _
Where c.<userid>.Value = "XXXX" _
Select c
В приведенном выше коде также не используется оператор LIKE. Таким образом, частичные совпадения не работают. Похоже, что я бы хотел использовать это .Startswith, но это похоже только на Linq2SQL. Любые рекомендации будут оценены. Я новичок в Linq, поэтому, возможно, я пропустил простой способ сделать это.
файл XML выглядит так:
<?xml version="1.0" standalone="yes"?>
<theusers>
<Users>
<userid>person1</userid>
<nickname></nickname>
<lastname></lastname>
<firstname></firstname>
<department></department>
<telephoneNumber></telephoneNumber>
<email></email>
</Users>
<Users>
<userid>person2</userid>
<nickname></nickname>
<lastname></lastname>
<firstname></firstname>
<department></department>
<telephoneNumber></telephoneNumber>
<email></email>
</Users>
######## UPDATE ######## Ниже приводится полный рабочий раствор в VB благодаря нашему доброжелательному ответчику.
Вот запрос вы бы запустить:
Dim query = From d In m_DataSet.Descendants("Users") _
Where d.ChildrenBeginWith(rezsplit) _
Select d
Вот метод расширения:
Public Module SearchEngine
<System.Runtime.CompilerServices.Extension()> _
Public Function ChildrenBeginWith(ByVal parent As XElement, _
ByVal ParamArray searchTerms As String()) As Boolean
Dim ret As Boolean = False
Dim children = parent.Elements().ToList()
For Each searchTerm In searchTerms
ret = children.Any(Function(x) x.Value.StartsWith(searchTerm))
If Not ret Then
Exit For
End If
Next
Return ret
End Function
End Module
Ничего себе, это здорово. Это значительно упрощает то, что у меня было в голове. Я полагаю, что осталось только выяснить несколько терминов. Если у меня есть только один поисковый запрос, ваше решение идеально. Мне нужно обрабатывать несколько. Поэтому, если пользователь передает Бобу 800-123-5555, тогда bob должен получить удар от псевдонима или имени, а номер телефона - номер телефона. –
Хорошо. Я думаю, что я ближе, если я делаю Where d.Elements(). Any (Function (x As XElement) x.Value.StartsWith (tempStr)) AND _ Где d.Elements(). Any (Функция (x As XElement) x.Value.StartsWith (tempStr2)) Он перемещает меня в правильном направлении. Знаете ли вы, как это было бы чисто для X-термина? –
Я не знаю, как правильно сделать то, что вы хотите изначально, поэтому я написал быстрый пример метода расширения, чтобы помочь вам (извините, что он находится в C#, но, надеюсь, он все равно поможет вам). –