2016-11-16 83 views
0

我有一个名为Person类,其具有的属性FirstNameLastNameMiddleName和我有一个表格宽SortedDictionary(整数,人)称为oPeopleLINQ SqlMethods.Like(和。载)失败

在上,我调用了一个加载65人列表的方法。现在这是硬编码,但最终我会从数据库中抓取它。

一旦形式被加载的,我有TextBox称为txtSearchForName供用户输入搜索项,并具有该系统期待通过oPeople滤波上LastName一个完整的或部分匹配(不区分大小写)。

最终我希望能够搜索FirstName,LastName和MiddleName(如果有的话)之间的比较。

在这一点上,我想要做的就是循环LINQ查询的结果并将它们输出到控制台窗口。

这里的Person类:

Public Class Person 

    Private _fnm As String = String.Empty 
    Public Property FirstName() As String 
     Get 
      Return _fnm 
     End Get 
     Set(ByVal value As String) 
      _fnm = value.Trim 
     End Set 
    End Property 

    Private _lnm As String = String.Empty 
    Public Property LastName() As String 
     Get 
      Return _lnm 
     End Get 
     Set(ByVal value As String) 
      _lnm = value.Trim 
     End Set 
    End Property 

    Private _mnm As String = String.Empty 
    Public Property MiddleName() As String 
     Get 
      Return _mnm 
     End Get 
     Set(ByVal value As String) 
      _mnm = value.Trim 
     End Set 
    End Property 

    Public Sub New() 
    End Sub 

    Public Sub New(ByVal firstName As String, 
        ByVal lastName As String, 
        Optional ByVal middleName As String = "") 

     _fnm = firstName 
     _lnm = lastName 
     _mnm = middleName 

    End Sub 

End Class 

这是我使用的是添加人的方法。我添加65人,但已削减代码下来:

Private Sub FillPeopleDictionary() 

    Try 

     If oPeople.Count > 0 Then oPeople.Clear() 

     Dim oNewPerson As Person = Nothing 

     oNewPerson = New Person("Scarlett", "Johansson") 
     oPeople.Add(1, oNewPerson) 

     oNewPerson = New Person("Amy", "Adams") 
     oPeople.Add(2, oNewPerson) 

     oNewPerson = New Person("Jessica", "Biel") 
     oPeople.Add(3, oNewPerson) 

    Catch ex As Exception 

     MessageBox.Show(ex.Message, "Error [FillPeopleDictionary]", MessageBoxButtons.OK, MessageBoxIcon.Error) 

    End Try 

End Sub 

这是我的LINQ语句,然后输出到控制台被称为当用户点击一个按钮:

Dim sSearchTerm As String = txtSearchForName.Text.Trim.ToLower 

Dim queryResults = From person In oPeople 
'Where SqlMethods.Like(person.Value.LastName.ToLower, "%" & sSearchTerm & "%") 
'Where person.Value.LastName.ToLower.Contains("%" & sSearchTerm & "%") 

Console.WriteLine("search term: " & sSearchTerm & 
        Environment.NewLine & Environment.NewLine & 
        "queryResults.Count: " & queryResults.Count.ToString & 
        Environment.NewLine) 

For Each result In queryResults 

    If Not String.IsNullOrEmpty(result.Value.MiddleName) Then 

     Console.WriteLine(result.Key.ToString.PadLeft(2, "0") & ": " & result.Value.FirstName & " " & result.Value.MiddleName & " " & result.Value.LastName) 

    Else 

     Console.WriteLine(result.Key.ToString.PadLeft(2, "0") & ": " & result.Value.FirstName & " " & result.Value.LastName) 

    End If 

Next 

的LINQ陈述按原样运作,没有条件,因此它循环并正确列出oPeople集合中的所有人员。

在最初的queryResults声明下方有两个Where条款注释。这是我试图过滤的两种方式。一种方法是使用.Contains,另一种方法是使用.Like,但都不起作用。

如果该用户输入“月”,我希望从65(不区分大小写)列表中取回的6人名单:

梅根马克尔
玛格特·罗比
凯特马拉
玛丽·伊丽莎白·文斯蒂德
玛丽安里维拉
艾米智能

现在当然即在FirstNameLastName上搜索。现在我只是想让LastName工作。在只有LastName名单就只能是:

梅根马克尔
凯特·玛拉
艾米智能

有人能看到我在做什么错在这里?或者我应该废除与SortedDictionary一起使用LINQ的想法?

+2

?此外,感谢您发布130 *双行*显示您如何添加60个人。我们大多数人会在2或3之后得到想法。请参阅[MCVE] – Plutonix

+0

Plutonix - 我只使用SQLMethods,因为我只是想了解LINQ如何工作。这是我第一次尝试使用它,所以我认为最好从我感到舒服的一些东西开始(SortedDictionaries)。 Jinx88909向我展示了List(Of T)是一个更好的方法。 –

+0

'SqlMethods'适用于Linq to SQL。你不需要它来了解linq或扩展方法,如答案 – Plutonix

回答

0

将您的Person类更改为包括PersonId,并将其传递至oNewPerson = New Person(1, "Scarlett", "Johansson")

将人物改为List(Of Person),因此添加时看起来像这样oPeople.Add(oNewPerson)。然后

你的LINQ的语句应该是这样的:

Dim queryResults = From person In oPeople 
        Where person.FirstName.ToLower Like "*" & sSearchTerm & "*" Or 
         person.LastName.ToLower Like "*" & sSearchTerm & "*" 

你也想改变,其余为使用字典不再:

For Each result In queryResults 

    If Not String.IsNullOrEmpty(result.MiddleName) Then 

     Console.WriteLine(result.PersonId.ToString.PadLeft(2, CChar("0")) & ": " & result.FirstName & " " & result.MiddleName & " " & result.LastName) 

    Else 

     Console.WriteLine(result.PersonId.ToString.PadLeft(2, CChar("0")) & ": " & result.FirstName & " " & result.LastName) 

    End If 

Next 

希望这有助于。

+1

这解决了它。正如我想了解更多关于LINQ的信息,我确实有一个问题。 LINQ不适用于已排序的字典吗?我不反对使用列表(T)我只是好奇。感谢您花时间充分解释发生了什么变化并提供了代码。这是非常赞赏。 –

+0

是的,它仍然可以工作,但是觉得在类中弹出PersonId而不是字典是有好处的,那么你可以引用该属性而不是.Key作为Id或.Value.FirstName。对我来说,这只是一个小清洁剂。很高兴它解决了这个问题。 – Bugs

0

你的第二Where条款试图接近,除了Contains功能有String.Contains不使用SQL使用%通配符,所以你需要:

Dim queryResults = 
    From person In oPeople 
    Where person.Value.LastName.ToLower.Contains(sSearchTerm) 

您可以轻松地添加支票FirstNameOrElse person.Value.FirstName.ToLower.Contains(sSearchTerm)

+0

谢谢你的帮助。我根据Jinx88909的回复。我确实包含了你对OrElse的建议。完美工作。感谢您的帮助。 –

0

更改您的LINQ查询,如下:你为什么要使用`SqlMethods`一个共同的普通NET收集

Dim queryResults = From p In oPeople 
           Where p.Value.FirstName.ToLower.Contains(sSearchTerm) Or p.Value.LastName.ToLower.Contains(sSearchTerm) 
+0

我试过这个,但它仍然给我没有结果。我不确定我做错了什么。我结束了Jinx88909的回应。感谢您花时间。这是非常赞赏。 –