【问题标题】:How do I append a 'where' clause using VB.NET and LINQ?如何使用 VB.NET 和 LINQ 附加“where”子句?
【发布时间】:2021-05-25 06:54:25
【问题描述】:

我对 VB.NET 还是很陌生,在这里遇到了一些我认为应该很简单的问题。

为简单起见,假设我有一个带有“名称”的 Document 表,我想在其上进行搜索(实际上还有其他几个表、连接等......)。我需要能够根据传入的字符串值使用where 子句构建查询。

示例 - 用户可以传入“ABC”、“ABC DEF”、“ABC DEF GHI”。

最终的查询将是(我知道语法不正确):

Select * from Documents Where Name Like %ABC% AND Name Like %DEF% AND Name like %GHI%

所以,我想我可以做这样的事情。

Dim query = From document In _context.Documents

<< loop based on number of strings passed in >>
query = query.Where( ... what goes here?? )

由于某种原因,脑死亡或其他原因,我无法弄清楚如何在 VB.NET 中使其工作,或者我是否正确地做到了。

【问题讨论】:

    标签: vb.net linq where-clause


    【解决方案1】:

    我相信这就是您在 VB 中的做法(我是 C# 开发人员):

    query = query.Where(Function(s) s = "ABC")
    

    请参阅 LINQ - Sample Queries 了解一些示例。

    【讨论】:

    • VB 的比较运算符和赋值运算符一样。所以's == "ABC"' 应该是'("ABC" = s)'。除此之外,干得好。
    • 不,那不是 LINQ,那是 Lambda。
    • 其实两者都有。这是使用 Lamda 表达式的 LINQ 方法语法示例。
    • 在 VB 中,LINQ 运算符是大写的。所以它的query.Where(...
    • 已修复!谢谢@ToolmakerSteve!
    【解决方案2】:

    我认为这里的棘手部分是未知数量的查询参数。您可以在此处使用底层 LINQ IQueryable(Of T) 来提供帮助。

    我认为以下方法可行(未编译,此处仅为记事本代码):

    Public Function GetDocuments(criteria as String)
        Dim splitCriteria = SplitTheCriteria(criteria)
    
        dim query = from document in _context.Documents
    
        For Each item in splitCriteria
            Dim localItem = item
            query = AddCriteriaToQuery(query, localItem)
        Next
    
        dim matchingDocuments = query.ToList()
    End Function
    
    Private Function AddCriteriaToQuery(query as IQueryable(Of Document), criteria as string) as IQueryable(Of Document)
         return query.Where(Function(doc) doc.Name = criteria)
    End Function
    

    由于 LINQ 会延迟执行查询,您可以在循环中将 where 子句附加到您的查询中,然后在最后调用 .ToList() 来执行查询。

    【讨论】:

    • 有效,但简单!这有助于解决我遇到的问题。
    【解决方案3】:

    在 LINQ to SQL 中,您可以使用查询对象的 .Where 方法将 WHERE 子句添加到查询中,正如您在问题中所指出的那样。要使用 LIKE 运算符,请尝试在调用 Where 方法的 Lambda 表达式中使用您正在查询的对象的 .Contains 方法。

    这是控制台应用程序中的一个简化示例。希望它会引导您朝着正确的方向前进。

    Public Class Doc
    
        Private _docName As String
        Public Property DocName() As String
            Get
                Return _docName
            End Get
            Set(ByVal value As String)
                _docName = value
            End Set
        End Property
    
        Public Sub New(ByVal newDocName As String)
            _docName = newDocName
        End Sub
    End Class
    
    Sub Main()
        Dim Documents As New List(Of Doc)
        Documents.Add(New Doc("ABC"))
        Documents.Add(New Doc("DEF"))
        Documents.Add(New Doc("GHI"))
        Documents.Add(New Doc("ABC DEF"))
        Documents.Add(New Doc("DEF GHI"))
        Documents.Add(New Doc("GHI LMN"))
    
        Dim qry = From docs In Documents
    
        qry = qry.Where(Function(d) d.DocName.Contains("GHI"))
    
        Dim qryResults As List(Of Doc) = qry.ToList()
    
        For Each d As Doc In qryResults
            Console.WriteLine(d.DocName)
        Next
    
    End Sub
    

    注意 .Where 方法的 Lambda 表达式中的 .Contains("GHI") 调用。我引用了表达式的参数“d”,它公开了 DocName 属性,进一步公开了 .Contains 方法。这应该会产生您期望的 LIKE 查询。

    此方法是附加的,即对 .Where 方法的调用可以包含在一个循环中,以便将额外的 LIKE 运算符添加到查询的 WHERE 子句中。

    【讨论】:

      【解决方案4】:
      Dim query = From document In _context.Documents where document.name = 'xpto' select document 
      

      或者

      Dim query = From document In _context.Documents where document.name.contains('xpto') select document 
      

      【讨论】:

        【解决方案5】:

        如果你在循环中这样做,你可以这样做:

        .Where(Function(i as mytype) i.myfiltervar = WhatIWantToSelect)
        

        【讨论】:

          猜你喜欢
          • 2014-12-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-26
          • 1970-01-01
          • 2023-03-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多