为什么使用创建lambda的函数替换IQueryable.Sum选择器中的lambda会失败? (错误1025)

时间:2012-07-26 23:35:15

标签: linq lambda linq-to-entities

我想抽象一个我有的lambda函数,它根据状态总结我的数据库中的记录。问题是,当我对LINQ to Entities运行生成的lambda时,我得到“内部.NET Framework数据提供程序错误1025”。 (仅供参考,它可以很好地对抗LINQ to Objects)。

以下是代码:

    <Extension()> _
    Public Function Summarize(ByVal auditsToSummarize As IQueryable(Of HvacAudit)) As IQueryable(Of HvacAuditSummary)
        Return From audit In auditsToSummarize
               Group By month = audit.DateCreated.Value.Month Into g = Group
               Select New HvacAuditSummary With {
                    .GroupingKey = month,
                    .Pending = g.Sum(Function(audit) If(audit.AuditStatusInt = CType(AuditStatus.Pending, Integer), 1, 0)),
                    .Issued = g.Sum(Function(audit) If(audit.AuditStatusInt = CType(AuditStatus.Issued, Integer), 1, 0)),
                    .Closed = g.Sum(Function(audit) If(audit.AuditStatusInt = CType(AuditStatus.Closed, Integer), 1, 0)),
                    .Cancelled = g.Sum(Function(audit) If(audit.AuditStatusInt = CType(AuditStatus.Cancelled, Integer), 1, 0))
                }
    End Function

以下是我尝试使用lambda生成器的示例:

    Select New HvacAuditSummary() With {
        .Cancelled = g.Sum(AuditsWithStatus(AuditStatus.Cancelled))
    }

    Private Function AuditsWithStatus(auditStatus As AuditStatus) As Func(Of HvacAudit, Integer)
        Return Function(audit) If(audit.AuditStatusInt = CType(auditStatus, Integer), 1, 0)
    End Function

注意:我已经查看了这个错误的其他问题,他们似乎都专注于使用错误的LINQ,因为使用lambda(Func)代替表达式。在sum方法中,所有候选人似乎都采用了Func,所以我不知道还有什么可以改变。

2 个答案:

答案 0 :(得分:1)

实体框架查询提供程序不知道您的函数AuditsWithStatus。 EF尝试将linq语句中的所有转换为sql,并且它只能处理一组受限制的.Net函数,它们知道sql等价物。对于其余部分,linq语句中的所有内容都必须是表达式(Expression<Func<...>>)。

这意味着:您可以使用您的功能,但只能 后使用ToList()ToArray(),这会将其转换为linq-to-objects。或者你必须把你的功能变成一个表达式。

答案 1 :(得分:-1)

查看您的匿名功能。

.Sum期待在C#中我们称之为Func&lt; bool&gt;。你返回1或0,这是整数或双重的隐含(我忘记了哪一个,但它在你的问题的背景下是不重要的。)

长话短说 - 真或假,不是1或0!