我有一个应用程序,当单击搜索按钮时,该应用程序从数据库绘制元素。我需要对其进行更新,以便我可以找到在字符串中恰好有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
查询中使用的扩展方法的方法。有什么想法吗?
答案 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)
行
这很简单地解决了我的问题。