我正在从ADO.NET迁移到Linq。该应用程序是一个目录搜索程序,以查找人。允许用户在单个文本框中键入搜索条件。他们可以用空格分隔每个术语,或者在引号中包含一个短语,例如“park place”,表示它是一个术语。
在幕后,数据来自一个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>
########更新######## 以下是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
答案 0 :(得分:1)
如果您只想要与linq-to-xml一起使用的东西,可以将xml加载到XDocument中并执行以下查询。它将包括以指定文本开头的任何子节点值。
Dim doc = XDocument.Parse("this is where your xml string goes")
Dim query = From d In doc.Descendants("Users") _
Where d.Elements().Any(Function(x As XElement) x.Value.StartsWith(tempStr)) _
Select d
For Each A In query
//Do Something
Next
编辑抱歉,我不是VB人,所以下面的示例是c#(我最初在c#中写了我的第一个答案,但我很容易转换为vb)。我不知道干净地做你想要的本地方式,所以最简单的方法可能是帮助方法或扩展方法,如下所示:
新查询:
var query = from d in doc.Descendants("Users")
where d.ChildrenBeginWith(tempStr, tempStr2)
select d;
扩展方法:
public static class Extension
{
public static bool ChildrenBeginWith(this XElement parent, params string[] searchTerms)
{
bool ret = false;
var children = parent.Elements().ToList();
foreach (var searchTerm in searchTerms)
{
ret = children.Any(x => x.Value.StartsWith(searchTerm));
if (!ret)
break;
}
return ret;
}
}