LINQ 查询到 LINQ 方法;为啥我需要 CBool​​?

Posted

技术标签:

【中文标题】LINQ 查询到 LINQ 方法;为啥我需要 CBool​​?【英文标题】:LINQ Query to LINQ Method; Why do I need CBool?LINQ 查询到 LINQ 方法;为什么我需要 CBool​​? 【发布时间】:2018-05-24 13:51:42 【问题描述】:

当我开始使用实体框架时,我使用查询语法,因为我更习惯使用 SQL 而不是方法。现在我了解了如何使用 Method,因此我将一些较旧的 LINQ Query 转换为 Method,因为我发现 Method 从编程的角度来看更有意义。

我的问题是,为什么编译器希望我在某些 where 项周围使用 CBool​​() 而不是其他项?它在 C# 中不这样做,只有 VB。

示例;

这个

TotalYearWages = If((From t In DB.interview_earnings
    Where t.IID = Input.ID AndAlso  t.EarningsYear = Input.EarningsYear
    Select t.Amount).Sum, 0)

变成这样

TotalYearWages = If(DB.interview_earnings.
    Where(Function(t) t.IID = Input.ID AndAlso CBool(t.EarningsYear = Input.EarningsYear)).
    Select(Function(t) t.Amount).Sum(), 0)

但在 c# 中这工作正常

TotalYearWages == DB.interview_earnings
    .Where(t => t.IID == Input.ID && t.EarningsYear == Input.EarningsYear)
    .Select(t => t.Amount).Sum() ?? 0

我的问题;

为什么我必须在 where 子句的某些部分使用 CBool​​,而在其他部分不用?什么决定了需求?

编辑;

没有 CBool​​ 我得到的错误是;

Severity    Code    Description Project File    Line    Suppression State
Error   BC30512 Option Strict On disallows implicit conversions from 'Boolean?' to 'Boolean'.   WOTC-FE d:\Programming\WOTC-Projects\WOTC-FE\Class\Billing.vb   129 Active

类构造函数是;

Imports System
Imports System.Collections.Generic

Partial Public Class interview_earnings
    Public Property ID As Integer
    Public Property IID As Integer
    Public Property CLIENTCODE As String
    Public Property ClientLocation As String
    Public Property EarningsDate As Nullable(Of Date)
    Public Property UserName As String
    Public Property Amount As Nullable(Of Decimal)
    Public Property Hours As Nullable(Of Decimal)
    Public Property InvDate As Nullable(Of Date)
    Public Property InvNumber As Nullable(Of Short)
    Public Property Notes As String
    Public Property EarningsYear As Nullable(Of Short)
    Public Property TCPercent As Nullable(Of Byte)
    Public Property WTWBill As Nullable(Of Boolean)
    Public Property WTW2yrBill As Nullable(Of Boolean)
    Public Property Refund As Nullable(Of Boolean)

    Public Overridable Property interview_main As interview_main

End Class

输入是

Public Class WageInfo
    Public Property ID As Integer
    Public Property NewYTDWage As Decimal?
    Public Property Limit As Integer?
    Public Property WOTC As Boolean
    Public Property EarningsRemaining As Decimal?
    Public Property EarningsYear As Short
    Public Property ThirdYearCalculation As Boolean
    Public Property WTW2Base As Decimal?
    Public Property WageWTW2Yr As Decimal?
    Public Property WageWOTC As Decimal?
    Public Property StartDate As Date?
    Public Property EarningsDate As Date
End Class

【问题讨论】:

如果您删除CBool,您会收到什么错误消息? 向问题添加错误代码 【参考方案1】:

当您需要可空变量的基础值时,请使用 Value 方法。这适用于 vb.net 和 c#。

TotalYearWages = If(DB.interview_earnings.
    Where(Function(t) t.IID = Input.ID AndAlso t.EarningsYear.Value = Input.EarningsYear).
    Select(Function(t) t.Amount).Sum(), 0)

如果合乎逻辑,我建议您在数据库中将这两个字段设为同一类型。

而且 c# 和 vb.net 编译器是不同的。 Option Strict On 不会使 vb.net 的行为与 c# 完全相同。

编辑:

此解决方案将处理 interview_earnings.EarningsYear 中的 NULL

TotalYearWages = If(DB.interview_earnings.
    Where(Function(t) t.IID = Input.ID AndAlso t.EarningsYear.Equals(Input.EarningsYear)).
    Select(Function(t) t.Amount).Sum(), 0)

【讨论】:

使用价值有效。我想这就像我可以使用什么?在执行 .ToShortDateString() 时,如果值为 null 而不会引发错误,则不会打扰。 如果那是一个 linq2objects 表达式,您将面临该代码出现 Null ref 异常的风险。 @Magnus 你是对的。我正在修改我的答案以更好地处理它。

以上是关于LINQ 查询到 LINQ 方法;为啥我需要 CBool​​?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Lambda 变量范围存在于 LINQ 查询之外?

使用 LINQ 进行递归控制搜索

使用 LINQ 进行递归控制搜索

为啥 LINQ 在我的查询中使用错误的数据类型,而它在 EF 架构中被正确声明?

关于为啥这个 linq ef 核心查询不会执行的建议

为啥 LINQ-to-Entities 将此查询放在子选择中?