LINQ Query to LINQ Method; Why do I need CBool?

entity-framework-6 lambda linq vb.net

Question

When I started using Entity Framework, I used Query Syntax as I was more used to using SQL than Method. Now I understand how to use Method, so I'm converting some of my older LINQ Query's to Method as I find that Method makes more sense from a programming perspective.

My question is, why does the compiler want me to use CBool() around some where items, but not others? It doesn't do this in C#, only VB.

Example;

This

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

Becomes this

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)

But in c# this works fine

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

My question;

Why do I have to use CBool around some parts of the where clause, but not around others? What determines the need?

Edit;

The error I get without the CBool is;

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

The Class Constructors are;

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

And

Input is

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
1
6
5/24/2018 2:59:28 PM

Accepted Answer

When you want the underlying value of a nullable variable, use the Value method. This applies to both vb.net and 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)

I suggest you make these two fields the same type in your database, if that is logical.

And c# and vb.net compilers are different. Option Strict On does not make vb.net behave exactly the same as c#.

Edit:

This solution will handle NULLs in interview_earnings.EarningsYear

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)
1
5/24/2018 3:53:50 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow