我目前正在为一系列数据库结果集编写一个包装器对象。这样做时,我在使用LINQ和Lambda表达式进行查询时注意到了一个问题。具体来说,在 lambda 中调用方法似乎总是使结果集为空,并且从未真正触发我尝试过滤的方法。这是代码:
' Query and filter container results
Public Function [Filter](pFilter As IFilter(Of T)) As System.Linq.IQueryable(Of T)
' THIS YIELDS AN EMPTY SET EVEN WHEN pFilter.Test(o) ALWAYS RETURNS TRUE
Dim lResult As System.Linq.IQueryable(Of T) = mTable.Where(Function(o As T) pFilter.Test(o))
Return lResult
End Function
pFilter 使用此签名实现 IFilter:
Public Interface IFilter(Of T)
Function Test(ByVal pObject As T) As Boolean
End Interface
我已经断了点pFilter.Test(o)
,发现它实际上从未被调用过。奇怪的是,如果我替换pFilter.Test(o)
为 True,我会按预期收到整个记录表。此外,在任何情况下,我都没有收到编译时或运行时错误。
我对Lambdas和LINQ还很陌生,所以我完全认识到我可能不明白我试图完成的事情的局限性。任何帮助是极大的赞赏!
解决方案:我已经标记了一个解决方案,因为作者让我走上了正确的轨道。这个问题的真正本质源于我试图将 .NET 函数强制转换为 LINQ 可以转换为 SQL 语句的东西(这是不可能的)。为了解决这个问题,我将 IFilter 更改为返回 System.Linq.Expressions.Expression(Of Func(Of T, Boolean)) 用于 Test 方法。现在我可以创建强类型过滤器,它返回谓词并将它们直接传递给 Where() 而不使用 lambda 表达式。我还使用LinqKit让那些可能正在完成类似任务的人更轻松地完成这项工作。