Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VB expression tree differences #69

Open
lorcQc opened this issue Dec 17, 2021 · 6 comments
Open

VB expression tree differences #69

lorcQc opened this issue Dec 17, 2021 · 6 comments

Comments

@lorcQc
Copy link
Collaborator

lorcQc commented Dec 17, 2021

VB generates differences in expression trees which can cause annoying issues when using EFCore.

If you are experiencing any of these issues, you can report it here. I will sort them and then open the tickets on the main repository.

They can also help us in creating functional tests later. dotnet/efcore#14572

@lorcQc
Copy link
Collaborator Author

lorcQc commented Dec 17, 2021

Dim query = From Post In db.Posts
            Group Post By Key = Post.AuthorId Into Group
            Select Key, Group.Count

System.InvalidOperationException: 'The LINQ expression '$VB$ItAnonymous' could not be translated.

DbSet<Post>()
    .GroupBy(
        keySelector: Post => Post.AuthorId, 
        elementSelector: Post => Post, 
        resultSelector: (Key, $VB$ItAnonymous) => new VB$AnonymousType_0<int, IEnumerable<Post>>(
            Key = Key, 
            Group = $VB$ItAnonymous
        ))
    .Select($VB$It => new VB$AnonymousType_1<int, int>(
        Key = $VB$It.Key, 
        Count = $VB$It.Group
            .Count()
    ))

Reported as dotnet/efcore#30773

@lorcQc
Copy link
Collaborator Author

lorcQc commented Dec 17, 2021

Dim query2 = From B In db.Blogs
             From P In B.Posts
             Group P By B.Rating Into G = Group
             Select Rating, G.Count

System.InvalidOperationException: 'The LINQ expression 'B => (IEnumerable<Post>)B.Posts' could not be translated.

DbSet<Blog>()
    .SelectMany(
        collectionSelector: B => (IEnumerable<Post>)B.Posts, 
        resultSelector: (B, P) => new VB$AnonymousType_2<Blog, Post>(
            B = B, 
            P = P
        ))
    .GroupBy(
        keySelector: $VB$It => $VB$It.B.Rating, 
        elementSelector: $VB$It => $VB$It.P, 
        resultSelector: (Rating, $VB$ItAnonymous) => new VB$AnonymousType_3<int?, IEnumerable<Post>>(
            Rating = Rating, 
            G = $VB$ItAnonymous
        ))
    .Select($VB$It => new VB$AnonymousType_4<int?, int>(
        Rating = $VB$It.Rating, 
        Count = $VB$It.G
            .Count()
    ))

Reported as dotnet/efcore#29185

@lorcQc
Copy link
Collaborator Author

lorcQc commented Dec 18, 2021

Note : VB use three-valued logic when comparing nullable value types

Here, Rating is a Nullable<int>

Dim query = From B In db.Blogs
            Where B.Rating <> 4

Generate this query which can be optimized...
With UseRelationalNulls (True)

SELECT [b].[Id], [b].[Rating], [b].[Url]
FROM [Blogs] AS [b]
WHERE COALESCE(CASE
    WHEN [b].[Rating] <> 4 THEN CAST(1 AS bit)
    ELSE CAST(0 AS bit)
END, CAST(0 AS bit)) = CAST(1 AS bit)

with UseRelationalNulls(False)

SELECT [b].[Id], [b].[Rating], [b].[Url]
FROM [Blogs] AS [b]
WHERE COALESCE(CASE
    WHEN ([b].[Rating] <> 4) OR [b].[Rating] IS NULL THEN CAST(1 AS bit)
    ELSE CAST(0 AS bit)
END, CAST(0 AS bit)) = CAST(1 AS bit)
DbSet<Blog>()
    .Where(B => B.Rating != ConvertChecked(4, Nullable`1)
     ?? False)

Reported as dotnet/efcore#27202

@lorcQc
Copy link
Collaborator Author

lorcQc commented Jan 20, 2022

Note, there is an issue on the main repo for the comparison issue with nullable types :
dotnet/efcore#27202

@bricelam
Copy link
Member

/cc @smitpatel @maumar

@lorcQc
Copy link
Collaborator Author

lorcQc commented Apr 14, 2022

I added some simple functional tests here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants