【问题标题】:Is there any way to write a LINQ Query,for condition like where IDs is in ('ID1','ID2','ID3','ID4'). in(VB.Net)有什么方法可以编写 LINQ 查询,例如 ID 所在的位置('ID1'、'ID2'、'ID3'、'ID4')。在(VB.Net)
【发布时间】:2021-04-19 14:41:04
【问题描述】:

我想在 VB.Net 中使用 LINQ Query 编写 SQL 查询, 有人可以建议是否有任何写法吗?

Select Count(Distinct(User_ID)) from tbl_CTRL where Req_ID = "R1" AND User_ID in ('001','002','004','005')

表:tbl_CTRL

 User_ID        Req_ID
   001          R1
   002          R2
   003          R1  
   004          R1
   005          R2
   001          R2
   002          R3

预期输出为: 计数= 2

【问题讨论】:

  • 您没有提及存储行的变量的名称,也没有提及这些行是否是自定义类、DataTable 或其他东西的集合。

标签: vb.net linq linq-to-sql linq-to-entities


【解决方案1】:

这是你想要的吗?

    'Assuming you have a DataTable
    'Dim tbl_CTRL As DataTable = New DataTable 
    Dim elCounts As Integer = (From element In tbl_CTRL
                               Where {"001", "002", "004", "005"}.Contains(CStr(element.Field(Of Object)("User_ID")))
                               Select element
                               Distinct).Count

【讨论】:

    【解决方案2】:

    以下内容尚未经过全面测试,但应该可以满足您的需求。在下面的示例中,动态创建 WHERE IN 条件时使用参数而不是注入,在这种情况下使用逗号分隔的命令值列表。

    完整的工作代码示例可以在以下GitHub repository中找到。

    终于SQL

    SELECT C.CustomerIdentifier ,
                       C.CompanyName ,
                       C.ContactName ,
                       C.ContactTypeIdentifier ,
                       FORMAT(C.ModifiedDate, 'MM-dd-yyyy', 'en-US') AS ModifiedDate,
                       CT.ContactTitle
                FROM   dbo.Customers AS C
                INNER JOIN dbo.ContactType AS CT ON C.ContactTypeIdentifier = CT.ContactTypeIdentifier
                WHERE CT.ContactTitle IN (@CTContactTitle0,@CTContactTitle1) AND Req_ID = "R1"
                ORDER BY C.CompanyName
    

    创建 WHERE IN 的代码

    Imports System.Data.SqlClient
    Imports System.Runtime.CompilerServices
    Imports System.Text.RegularExpressions
    
    ''' <summary>
    ''' Contains methods to create dynamic WHERE IN conditions on a single field
    ''' </summary>
    ''' <remarks>
    ''' These methods are not meant to handle every single condition, they are
    ''' for simple IN clauses e.g. 
    ''' 
    ''' WHERE SomeField IN (1,2,3)
    ''' WHERE SomeField IN ('June','April')
    ''' WHERE YEAR(SomeField) IN (2008,2007,2018)
    ''' WHERE SomeField IN ('4-4-1960','9-22-1989')
    ''' 
    ''' If a function is year that has arguments these methods will not handle
    ''' them "as is".
    ''' 
    ''' </remarks>
    Public Module SqlWhereInParameterBuilder
        ''' <summary>
        ''' Create a SQL SELECT statement which is then passed off to
        ''' AddParamsToCommand to create a parameter for each value.
        ''' </summary>
        ''' <typeparam name="T">SELECT Statement with WHERE condition</typeparam>
        ''' <param name="partialClause">Base SQL SELECT statement</param>
        ''' <param name="paramPrefix">WHERE IN field</param>
        ''' <param name="parameters">Value list for WHERE IN</param>
        ''' <returns>SELECT Statement with WHERE condition ready to populate values</returns>
        Public Function BuildWhereInClause(Of T)(partialClause As String, paramPrefix As String, parameters As IEnumerable(Of T)) As String
    
            paramPrefix = StripFunction(paramPrefix)
    
            Dim parameterNames = parameters.Select(
                Function(paramText, paramNumber) $"@{paramPrefix.Replace(".", "")}{paramNumber}").ToArray()
    
            Dim whereInClause = String.Format(partialClause.Trim(), String.Join(",", parameterNames))
    
            Return whereInClause
    
        End Function
        ''' <summary>
        ''' Create a parameter for each value in parameters
        ''' </summary>
        ''' <typeparam name="T">Command with parameters setup</typeparam>
        ''' <param name="cmd">Command object</param>
        ''' <param name="paramPrefix">Field name for the WHERE IN</param>
        ''' <param name="parameters">Values for the WHERE IN</param>
        <Extension>
        Public Sub AddParamsToCommand(Of T)(cmd As SqlCommand, paramPrefix As String, parameters As IEnumerable(Of T))
            paramPrefix = StripFunction(paramPrefix)
    
            Dim parameterValues = parameters.Select(Function(paramText) paramText).ToArray()
            Dim parameterNames() As String = parameterValues.Select(
                Function(paramText, paramNumber) $"@{paramPrefix.Replace(".", "")}{paramNumber}").ToArray()
    
            For index As Integer = 0 To parameterNames.Length - 1
                cmd.Parameters.AddWithValue(parameterNames(index), parameterValues(index))
            Next
    
            '
            ' Display what a hacker would see
            '
            If Debugger.IsAttached Then
                Console.WriteLine(cmd.CommandText)
            End If
    
        End Sub
        ''' <summary>
        ''' Used to get a field name from a function e.g. YEAR(ActiveDate)
        ''' which will return ActiveDate.
        ''' </summary>
        ''' <param name="pValue"></param>
        ''' <returns></returns>
        Private Function StripFunction(pValue As String) As String
            If pValue.Contains("(") Then
                Dim regularExpressionPattern As String = "(?<=\()[^}]*(?=\))"
                Dim re As New Regex(regularExpressionPattern)
                Return re.Matches(pValue)(0).ToString()
            Else
                Return pValue
            End If
        End Function
    End Module
    

    这是一个控制台项目(Imports SqlHelpers)中的粗略示例,是上面的一个类项目。

    Imports System
    Imports System.Data
    Imports SqlHelpers
    
    Module Program
        Sub Main(args As String())
            Dim contacts = New List(Of String) From {"May Jones", "Tim O'Brian"}
            Examples.ReadCustomersByContactType(contacts)
        End Sub
    End Module
    
    Public Class Examples
        Public Shared Function ReadCustomersByContactType(pContactTitleList As List(Of String)) As DataTable
    
            'mHasException = False
    
            ' field which the WHERE IN will use
            Dim parameterPrefix = "CT.ContactTitle"
    
            ' Base SELECT Statement
            Dim selectStatement =
                    <SQL>
                SELECT C.CustomerIdentifier ,
                       C.CompanyName ,
                       C.ContactName ,
                       C.ContactTypeIdentifier ,
                       FORMAT(C.ModifiedDate, 'MM-dd-yyyy', 'en-US') AS ModifiedDate,
                       CT.ContactTitle
                FROM   dbo.Customers AS C
                INNER JOIN dbo.ContactType AS CT ON C.ContactTypeIdentifier = CT.ContactTypeIdentifier
                WHERE <%= parameterPrefix %> IN ({0}) AND Req_ID = "R1"
                ORDER BY C.CompanyName
                </SQL>.Value
    
            ' Builds the SELECT statement minus values
            Dim CommandText = BuildWhereInClause(selectStatement, parameterPrefix, pContactTitleList)
    
            Dim dt As New DataTable
    
            Using cn As New SqlClient.SqlConnection
    
                Using cmd As New SqlClient.SqlCommand
    
                    cmd.CommandText = CommandText
    
                    '
                    ' Add values for command parameters
                    '
                    cmd.AddParamsToCommand(parameterPrefix, pContactTitleList)
                    Console.WriteLine()
                    Try
                        'cn.Open()
    
                        'dt.Load(cmd.ExecuteReader)
    
                    Catch ex As Exception
                        'mHasException = True
                        'mLastException = ex
                    End Try
    
                End Using
            End Using
    
            Return dt
    
        End Function
    End Class
    

    如果需要,在 Git 存储库中还有一个自定义文本框。

    【讨论】:

      猜你喜欢
      • 2015-07-12
      • 1970-01-01
      • 1970-01-01
      • 2019-06-09
      • 2019-06-19
      • 2011-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多