Type Converters
Handle custom type mappings between C# and database
Overview
Type converters allow you to customize how C# types are stored in and retrieved from the database. This is useful for types that don't have direct database equivalents or when you need custom serialization logic.
Creating a Type Converter
Implement ITypeConverter
C#
public interface ITypeConverter<TFrom, TTo>
{
TTo Convert(TFrom value);
TFrom ConvertBack(TTo value);
}
Or Extend TypeConverter Base Class
C#
public class DateTimeTicksConverter : TypeConverter<DateTime, long>
{
public override long Convert(DateTime value)
{
return value.ToUniversalTime().Ticks;
}
public override DateTime ConvertBack(long value)
{
return new DateTime(value, DateTimeKind.Utc);
}
}
Using Type Converters
Per-Property Converters
Apply the [TypeConverter] attribute to individual properties:
C#
[Entity(TableName = "posts")]
public class Post
{
[PrimaryKey(AutoGenerate = true)]
public long Id { get; set; }
public string Title { get; set; }
[TypeConverter(ConverterType = typeof(DateTimeTicksConverter))]
public DateTime PublishedAt { get; set; }
[TypeConverter(ConverterType = typeof(JsonConverter<List<string>>))]
public List<string> Tags { get; set; }
}
Global Converters
Register converters globally to apply them across all entities:
C#
var db = RoomDatabase.Builder<AppDatabaseImpl>()
.UseSqlite("app.db")
.Build();
// Register global converters
db.Converters.Register(new GuidToStringConverter());
db.Converters.Register(new DateTimeOffsetConverter());
Common Use Cases
1. DateTime to Ticks
C#
public class DateTimeTicksConverter : TypeConverter<DateTime, long>
{
public override long Convert(DateTime value)
=> value.ToUniversalTime().Ticks;
public override DateTime ConvertBack(long value)
=> new DateTime(value, DateTimeKind.Utc);
}
2. Guid to String
C#
public class GuidToStringConverter : TypeConverter<Guid, string>
{
public override string Convert(Guid value)
=> value.ToString("N");
public override Guid ConvertBack(string value)
=> Guid.Parse(value);
}
3. JSON Serialization
C#
public class JsonConverter<T> : TypeConverter<T, string>
{
public override string Convert(T value)
{
return JsonSerializer.Serialize(value);
}
public override T ConvertBack(string value)
{
return JsonSerializer.Deserialize<T>(value)
?? throw new InvalidOperationException("Deserialization failed");
}
}
// Usage
[Entity(TableName = "settings")]
public class AppSettings
{
[PrimaryKey]
public int Id { get; set; }
[TypeConverter(ConverterType = typeof(JsonConverter<UserPreferences>))]
public UserPreferences Preferences { get; set; }
}
4. Enum to String
C#
public class EnumToStringConverter<TEnum> : TypeConverter<TEnum, string>
where TEnum : struct, Enum
{
public override string Convert(TEnum value)
=> value.ToString();
public override TEnum ConvertBack(string value)
=> Enum.Parse<TEnum>(value);
}
Built-in Converters
RoomSharp includes built-in converters for common types:
DateTime→long(Unix ticks)bool→int(0 or 1)Guid→stringTimeSpan→long(ticks)DateTimeOffset→long(Unix milliseconds)
Converter Discovery
RoomSharp automatically discovers converters in this order:
- Property-level
[TypeConverter]attributes - Globally registered converters via
db.Converters.Register() - Built-in converters
Best Practices
- Keep converters simple and stateless
- Handle null values appropriately
- Consider using existing serialization libraries (JSON, MessagePack)
- Register global converters during application startup
- Document custom converters for your team
- Test converters with edge cases (null, empty, max values)
Performance Considerations
Type converters are called for every read/write operation:
- Keep
ConvertandConvertBackmethods fast - Avoid expensive operations (file I/O, network calls)
- Cache serializer instances when possible
- Consider using
Span<T>for large data conversions
Next Steps
- Entities - Learn about entity attributes
- Database Providers - Provider-specific considerations
- Performance Notes - Optimization tips

