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

Optimize out null checks when translating Enum flags #18725

Closed
BenjaminAbt opened this issue Nov 2, 2019 · 0 comments · Fixed by #18750

Comments

@BenjaminAbt
Copy link

@BenjaminAbt BenjaminAbt commented Nov 2, 2019

I have an enum with corresponding flags.
The goal now is to check whether a property has one of the passed flags.

    [Flags]
    public enum MyEnumWithFlags
    {
        None = -1,
        RoleA = 1,
        RoleB = 2,
        RoleC = 4,
        RoleD = 8,
        RoleE = 16
    }

    public class MyEntity
    {
          public int Id {get;set;}
          public MyEnumWithFlags MyPropertyWithFlags {get;set;}
     }

Steps to reproduce

 MyEnumWithFlags existingFlags = MyEnumWithFlags.RoleA | MyEnumWithFlags.RoleC;
 var query = await _dbContext.Entities.Where(e => (e.MyPropertyWithFlags & existingFlags) != 0)

Following SQL will be fired:

SELECT [f].[Id], [f].[MyEnumWithFlags] FROM [Entities] AS [f]
WHERE (([f].[MyEnumWithFlags] & @__existingFlags _0) <> 0) OR [f].[MyEnumWithFlags] & @__existingFlags _0 IS NULL)
      ORDER BY [f].[Id]

I don't think this is the correct query: the IS NULL check is unnecessary (column is "int, not null").
If the column could be null, this would even create a wrong query.

Further technical details

EF Core version: 3.0.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: 3.1.0-preview1.19506.1
Operating system: Windows 10
IDE: Visual Studio 2019 16.4 Preview 2

@BenjaminAbt BenjaminAbt added the type-bug label Nov 2, 2019
@ajcvickers ajcvickers added type-enhancement and removed type-bug labels Nov 4, 2019
@ajcvickers ajcvickers added this to the 5.0.0 milestone Nov 4, 2019
@ajcvickers ajcvickers changed the title Enum flags are not translated correctly Optimize out null checks when translating Enum flags Nov 4, 2019
maumar added a commit that referenced this issue Nov 4, 2019
One of the binary expression optimizations is op(a, b) == null -> a == null || b == null. This is valid for all binary operators except logical (AndAlso, OrElse). Before we used to also skip this optimization for bitwise (And, Or).
However, this optimization is valid for bitwise ops, so the fix is to enable it.

Resolves #18725
maumar added a commit that referenced this issue Nov 4, 2019
One of the binary expression optimizations is op(a, b) == null -> a == null || b == null. This is valid for all binary operators except logical (AndAlso, OrElse). Before we used to also skip this optimization for bitwise (And, Or).
However, this optimization is valid for bitwise ops, so the fix is to enable it.

Resolves #18725
@maumar maumar added the closed-fixed label Nov 4, 2019
@maumar maumar closed this in b2b6f7a Nov 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.