是否可以创建可在sql查询中使用的扩展方法?

时间:2019-07-29 15:48:46

标签: sql vb.net visual-studio

我有一个应用程序,当单击搜索按钮时,该应用程序从数据库绘制元素。我需要对其进行更新,以便我可以找到在字符串中恰好有6个位置的特定Substring元素。例如,我需要通过在第六和第七位查找33来找到111-2233-44-555。我的第一个直觉是为字符串类创建一个扩展方法,以便我可以这样说:

Dim example As String = "111-2233-44-555"
If example.HasYear(33) Then
  'Do Something'
End If

这很好用。这是我做的方法:

Public Module StringExtensionMethods
    ''' <summary>
    ''' Finds the year in a competition number of format XXX-XXXX-XX-XXX
    ''' </summary>
    ''' <param name="pstrCompNum">The competition number to find the year in</param>
    <Extension()>
    Public Function HasYear(ByVal pstrCompNum As String, ByVal pstrCompYear As String) As Boolean
        Try

            Dim testString As String = pstrCompNum

            Debug.Print(testString)
            Dim testSubstring As String = testString.Substring(6, 2)
            If testSubstring.Equals(pstrCompYear) Then
                Return True
            End If
            Return False

        Catch ex As Exception
            Throw ex
        End Try
    End Function
End Module

但是当我尝试在SQL查询中使用此方法时,会出现问题。没错,因为HasYear()SQL毫无关系。这是我要执行的查询:

Dim o = From c In myContext.Competitions.Include("CodeJusticeBranches").Include("CodeJusticeLocations").Include("CodeCompetitionTypes").Include("CodePositionTypes").Include("CompetitionPositions") _
                        Where (pstrCompNum Is Nothing OrElse c.comp_number = pstrCompNum) _
                        And (pstrCompYear Is Nothing OrElse c.comp_number.HasYear(strYear) = True) _
                        And (pstrCompTypeId Is Nothing OrElse c.CodeCompetitionTypes.code_ct_id = CInt(pstrCompTypeId)) _
                        And (pstrBranchId Is Nothing OrElse c.CodeJusticeBranches.code_branch_id = CInt(pstrBranchId)) _
                        And (pstrPosTypeId Is Nothing OrElse c.CodePositionTypes.code_pos_type_id = CInt(pstrPosTypeId)) _
                        Order By c.comp_number _
                        Select c

我收到错误LINQ to Entities,无法识别方法'Boolean HasYear(System.String,System.String)'方法,并且该方法无法转换为商店表达式。

因此,我所寻找的本质上是一种制作可在SQL查询中使用的扩展方法的方法。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

LINQ中不包括自定义函数。它必须可转换为SQL,因此您的扩展方法不符合条件。只需使用支持的where子句执行查询,然后再添加自定义查询即可。

Dim o = (
    From c In myContext.Competitions.Include("CodeJusticeBranches").Include("CodeJusticeLocations").Include("CodeCompetitionTypes").Include("CodePositionTypes").Include("CompetitionPositions")
    Where (pstrCompNum Is Nothing OrElse c.comp_number = pstrCompNum) _
    And (pstrCompTypeId Is Nothing OrElse c.CodeCompetitionTypes.code_ct_id = CInt(pstrCompTypeId)) _
    And (pstrBranchId Is Nothing OrElse c.CodeJusticeBranches.code_branch_id = CInt(pstrBranchId)) _
    And (pstrPosTypeId Is Nothing OrElse c.CodePositionTypes.code_pos_type_id = CInt(pstrPosTypeId))
    Order By c.comp_number Select c).ToList().
    Where(Function(c) c.pstrCompYear Is Nothing OrElse c.comp_number.HasYear(strYear))

答案 1 :(得分:0)

我喜欢@djv所发布的内容,但是我决定尝试执行安德鲁·莫顿(Andrew Morton)的建议,以完全省略HasYear()。我最终使用了这个:

Dim k = From c In myContext.Competitions.Include("CodeJusticeBranches").Include("CodeJusticeLocations").Include("CodeCompetitionTypes").Include("CodePositionTypes").Include("CompetitionPositions") _
                        Where (pstrCompNum Is Nothing OrElse c.comp_number = pstrCompNum) _
                        And (pstrCompYear Is Nothing OrElse c.comp_number.Substring(6, 2) = pstrCompYear) _
                        And (pstrCompTypeId Is Nothing OrElse c.CodeCompetitionTypes.code_ct_id = CInt(pstrCompTypeId)) _
                        And (pstrBranchId Is Nothing OrElse c.CodeJusticeBranches.code_branch_id = CInt(pstrBranchId)) _
                        And (pstrPosTypeId Is Nothing OrElse c.CodePositionTypes.code_pos_type_id = CInt(pstrPosTypeId)) _
                        Order By c.comp_number _
                        Select c

注意第And (pstrCompYear Is Nothing OrElse c.comp_number.Substring(6, 2) = pstrCompYear)

这很简单地解决了我的问题。