-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Closed
Description
Given a value converter such as:
public sealed class BooleanToCharConverter : ValueConverter<bool, char>
{
public static readonly BooleanToCharConverter Default = new();
public BooleanToCharConverter()
: base(v => ConvertToChar(v), v => ConvertToBoolean(v))
{
}
private static char ConvertToChar(bool value)
{
return value ? 'Y' : 'N';
}
private static bool ConvertToBoolean(char value)
{
return value == 'Y';
}
}
...generating a compiled model produces code that attempts to call the private conversion methods resulting in CS0122 compilation errors:
V:\dev\frankbuckley\ef-core-compiled-value-converter\Model\CompiledModels\SentenceEntityType.cs(42,57): error CS0122: 'BooleanToCharConverter.ConvertToChar(bool)' is inaccessible due to its protection level
V:\dev\frankbuckley\ef-core-compiled-value-converter\Model\CompiledModels\SentenceEntityType.cs(43,57): error CS0122: 'BooleanToCharConverter.ConvertToBoolean(char)' is inaccessible due to its protection level
Repro
using Microsoft.EntityFrameworkCore;
using Model;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using var context = new LanguageDbContext();
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
context.Sentences.Add(new Sentence { Text = "Hello, World!", IsPhrase = false });
context.SaveChanges();
var sentences = context.Sentences.ToList();
foreach (var sentence in sentences)
{
Console.WriteLine(sentence.Text);
}
namespace Model
{
public class Sentence
{
public int Id { get; set; }
public required string Text { get; set; }
public bool IsPhrase { get; set; }
}
public class LanguageDbContext : DbContext
{
public DbSet<Sentence> Sentences { get; set; } = default!;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
_ = optionsBuilder.UseSqlite("DataSource=temp.db");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Sentence>().Property(e => e.IsPhrase).HasConversion(Storage.BooleanToCharConverter.Default);
}
}
}
namespace Storage
{
public sealed class BooleanToCharConverter : ValueConverter<bool, char>
{
public static readonly BooleanToCharConverter Default = new();
public BooleanToCharConverter()
: base(v => ConvertToChar(v), v => ConvertToBoolean(v))
{
}
private static char ConvertToChar(bool value)
{
return value ? 'Y' : 'N';
}
private static bool ConvertToBoolean(char value)
{
return value == 'Y';
}
}
}
- Build
- Run
dotnet ef dbcontext optimize
- Build again (failes)
It would be preferable if the model compiler errors when referencing a private method rather than producing invalid code.
Workaround
- Make methods public (if you can)