CodeConverter icon indicating copy to clipboard operation
CodeConverter copied to clipboard

VB -> C#: wrong conversion of linq expression containing nullable value

Open KunzeAndreas opened this issue 3 years ago • 3 comments

VB.Net input code

Private Shared Sub LinqWithNullable()
    Dim a = New List(Of Integer?) From {1, 2, 3, Nothing}
    Dim result = From x In a Where x = 1
    Assert.That(result.Count = 1)
End Sub

Erroneous output

var result = from x in a
            where 1 is var arg2 && x is { } arg1 ? arg1 == arg2 : (bool?)null
            select x;

Expected output

var  result = from x in a
             where x.HasValue && x.Value == 1
             select x;

Details

  • Product in use: VS extension
  • Version in use: 9.0.0.0
  • Did you see it working in a previous version, which? no

KunzeAndreas avatar May 12 '22 10:05 KunzeAndreas

  1. To fix this: where expressions should be probably included in https://github.com/icsharpcode/CodeConverter/blob/db94fb3d006d53bb9fb1689a58febcc19db8cadd/CodeConverter/CSharp/VbSyntaxNodeExtensions.cs#L23
  2. Might be an opportunity to simplify the patterns that we have to generate to handle vb nullable logic correctly #860 At least we could simplify if lhs or rhs are constants.

Yozer avatar May 12 '22 11:05 Yozer

Yeah there was another issue related to not doing special VB string comparisons within the query syntax too

GrahamTheCoder avatar Jun 15 '22 21:06 GrahamTheCoder

I just had a problem like this too:

input:

Dim My_Agency_Entity_ID As Integer = (From e In db.Entities
                                     Where e.Is_Agency = True And e.Tax_ID = CType("123456789", Integer)
                                     Order By e.Entity_ID
                                     Select e.Entity_ID).First()

where e.Tax_ID is of type "int?"

output:

int My_Agency_Entity_ID = (from e in db.Entities
                          where e.Is_Agency == true & (Conversions.ToInteger("123456789") is var arg6 && e.Tax_ID is { } arg5 ? arg5 == arg6 : null)
                          orderby e.Entity_ID
                          select e.Entity_ID).First();

carden-jeremy avatar Aug 03 '22 17:08 carden-jeremy

I later found that the requested "expected output" throws on nulls when using EFCore anyway (I tested against sqlite). Since this sort of behaviour is provider specific, I've decided to remove special null propagation handling from query syntax conversions.

GrahamTheCoder avatar Jun 25 '23 17:06 GrahamTheCoder