1

我目前正在为一系列数据库结果集编写一个包装器对象。这样做时,我在使用LINQLambda表达式进行查询时注意到了一个问题。具体来说,在 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,我会按预期收到整个记录表。此外,在任何情况下,我都没有收到编译时或运行时错误。

我对LambdasLINQ还很陌生,所以我完全认识到我可能不明白我试图完成的事情的局限性。任何帮助是极大的赞赏!

解决方案:我已经标记了一个解决方案,因为作者让我走上了正确的轨道。这个问题的真正本质源于我试图将 .NET 函数强制转换为 LINQ 可以转换为 SQL 语句的东西(这是不可能的)。为了解决这个问题,我将 IFilter 更改为返回 System.Linq.Expressions.Expression(Of Func(Of T, Boolean)) 用于 Test 方法。现在我可以创建强类型过滤器,它返回谓词并将它们直接传递给 Where() 而不使用 lambda 表达式。我还使用LinqKit让那些可能正在完成类似任务的人更轻松地完成这项工作。

4

1 回答 1

1

我想我发现了你的问题——理解 IQueryable 的概念。这是它在这篇文章中所说的:使用 LazyList 进行延迟加载

IQueryable 是 Linq To Sql 的基石,并且(我认为)是一个杀手级功能:延迟执行。IQueryable 本质上为您创建了一个表达式,您可以将其视为一个可枚举的列表 - 只有当您迭代或请求一个值时,才会执行查询。

所以你可能从来没有使用过这个结果,这就是为什么它从来没有被调用过。.NET框架只是为你构建了表达式树,并没有做任何处理。

另请参阅:IQueryable 与 IEnumerable

于 2012-10-25T18:03:05.173 回答