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

Enum with EnumToStringConverter always returns 0 in query if cast to another type #27703

Closed
aayjaychan opened this issue Mar 25, 2022 · 2 comments

Comments

@aayjaychan
Copy link
Contributor

aayjaychan commented Mar 25, 2022

If an enum property has string conversion, querying the property with a cast will always return 0, regardless of what value the property has.

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <Nullable>enable</Nullable>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.3" />
        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
        <PackageReference Include="NUnit" Version="3.13.3" />
    </ItemGroup>

</Project>
using System;
using System.Linq;
using System.Threading.Tasks;

using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

using NUnit.Framework;

namespace EnumCast;

public class Entity
{
    public int Id { get; set; }
    public DateTimeKind DateTimeKind { get; set; }
}

public class EnumProjectionDbContext : DbContext
{
    public DbSet<Entity> Entities => Set<Entity>();

    public EnumProjectionDbContext(
        DbContextOptions<EnumProjectionDbContext> options) :
        base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        EntityTypeBuilder<Entity> entityTypeBuilder = modelBuilder.Entity<Entity>();

        entityTypeBuilder.Property(e => e.DateTimeKind)
            .HasConversion<EnumToStringConverter<DateTimeKind>>();
    }
}

public class EnumCastTests
{
    [Test]
    public async Task Retrieve_projected_nullable_enum()
    {
        await using SqliteConnection dbConnection = new("DataSource=:memory:");

        await dbConnection.OpenAsync();

        DbContextOptionsBuilder<EnumProjectionDbContext> dbOptionsBuilder =
            new DbContextOptionsBuilder<EnumProjectionDbContext>()
                .UseSqlite(dbConnection);
        await using EnumProjectionDbContext dbContext = new(dbOptionsBuilder.Options);
        DateTimeKind expected = DateTimeKind.Utc;
        Entity entity = new()
        {
            DateTimeKind = expected,
        };

        await dbContext.Database.EnsureCreatedAsync();
        dbContext.Entities.Add(entity);
        await dbContext.SaveChangesAsync();

        int actual = await dbContext.Entities
            .Select(e => (int)e.DateTimeKind)
            .FirstOrDefaultAsync();

        Assert.AreEqual(
            expected: (int)expected,
            actual: actual);
        // Expected: 1
        //   But was:  0
    }
}

Expected Behaviour

actual is 1 because DateTimeKind has a numeric value of 1.

Actual Behaviour

actual is 0.

Include provider and version information

EF Core version: 6.0.3
Database provider: Microsoft.EntityFrameworkCore.Sqlite
Target framework: .NET 6.0.3

@aayjaychan aayjaychan changed the title Enum with EnumToStringConverter always returns 0 in query if casted Enum with EnumToStringConverter always returns 0 in query if cast to another type Mar 28, 2022
@ajcvickers
Copy link
Member

@aayjaychan This is tracked by #10434 for the general case. However, I am curious why you want an int in this case?

@aayjaychan
Copy link
Contributor Author

@ajcvickers int is used as an example. In practice we tried to convert the enum to another enum, which is then returned by ASP.NET Core as string in a JSON API response. This allows us to change the names of the enum values in one layer without affecting the other. We now use a mapping function to work around the issue with projection.

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants