Skip to main content

Value Converters

Value converters allow property values to be converted when reading from or writing to the database. This conversion can be

  • from one value to another of the same type (for example, encrypting strings).
  • or from a value of one type to a value of another type (for example, converting enum values to and from strings in the database).

Value converters are specified in terms of a ModelClrType and a ProviderClrType:

  • The model type is the .NET type of the property in the entity type.
  • The provider type is the .NET type understood by the database provider.

Configuring a value converter

Value conversions are configured in DbContext.OnModelCreating. For example, consider an enum and entity type defined as:

public class Rider
{
public int Id { get; set; }
public EquineBeast Mount { get; set; }
}

public enum EquineBeast
{
Donkey,
Mule,
Horse,
Unicorn
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Rider>()
.Property(e => e.Mount)
.HasConversion(
v => v.ToString(),
v => (EquineBeast)Enum.Parse(typeof(EquineBeast), v));
}

The ValueConverter class

Calling HasConversion as shown above will create a ValueConverter<TModel,TProvider> instance and set it on the property. The ValueConverter can instead be created explicitly. For example:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var converter = new ValueConverter<EquineBeast, string>(
v => v.ToString(),
v => (EquineBeast)Enum.Parse(typeof(EquineBeast), v));

modelBuilder
.Entity<Rider>()
.Property(e => e.Mount)
.HasConversion(converter);
}

This can be useful when multiple properties use the same conversion.

Built-in converters

EF Core ships with a set of pre-defined ValueConverter<TModel,TProvider> classes, found in the Microsoft.EntityFrameworkCore.Storage.ValueConversion namespace. In many cases EF will choose the appropriate built-in converter based on the type of the property in the model and the type requested in the database.

For example, using .HasConversion<int>() on a bool property will cause EF Core to convert bool values to numerical zero and one values:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<User>()
.Property(e => e.IsActive)
.HasConversion<int>();
}

This is functionally the same as creating an instance of the built-in BoolToZeroOneConverter<TProvider> and setting it explicitly:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var converter = new BoolToZeroOneConverter<int>();

modelBuilder
.Entity<User>()
.Property(e => e.IsActive)
.HasConversion(converter);
}

A list of the built-in converters can be found in the Microsoft Docs.