Skip to main content

Value Converters

  • 4 minutes to read

There are situations when it is necessary to persist non-persistent property type values in a database. While this requirement can be addressed by creating an additional persistent property and performing the conversion between values, XPO provides a built-in mechanism for such scenarios. The Value Converter is a class that encapsulates conversion methods and can be reused for different properties. A value converter’s conversion algorithms are usually applied when the property value is loaded from or saved to the database.

To implement a property value converter, create a class inherited from the ValueConverter class and override its abstract members:

The value converter can be associated with a specific property by applying the ValueConverterAttribute attribute, or with a property type by calling the metadata dictionary’s XPDictionary.RegisterValueConverter method.

There’s a built-in ImageValueConverter you can apply to System.Drawing.Image properties to store them as BLOBs in the database.

Note that the TimeSpan and Enum types are persisted using the corresponding built-in Value Converters by default.

Note

The value converter mechanism is designed to allow persisting non-persistent data types by transforming them into a persistable equivalent. Value converters are not intended for introducing encryption, compression, or other business logic into the persistence process.

Important

  • Properties persisted using Value Converters require the client-side conversion logic, and should not be used in criteria expressions evaluated on the database server side. An attempt to use such properties in criteria may lead to undefined behavior. For instance, when a criterion is translated to a database query, a conversion implemented programmatically may not be applied or may be applied multiple times.

  • Value Converters cannot be applied to a property that represents a primary or foreign key. Use the approach described in the How to make user-friendly object identifiers Knowledge Base article if you need to use text values for object identifiers instead of auto-generated numbers.

Do not use value converters to filter or sort by a persistent type value transformed from a stored persistent value. Instead, create an additional calculated property decorated with PersistentAliasAttribute and express a conversion algorithm using the Criteria Language. If the algorithm is complex, implement a Custom Function Operator and use it in the criteria expression.

Example

The following code example demonstrates how to store your boolean data in the database using the “T” string for true and “F” for false by defining a new ValueConverter descendant. You may need this converter when using an existing database in which boolean properties are stored such form.

//...       
[Size(1), ValueConverter(typeof(BooleanToStringValueConverter))]
public bool Answer {
    get { return GetPropertyValue<bool>(nameof(Answer)); }
    set { SetPropertyValue<bool>(nameof(Answer), value); }
}

//...
public class BooleanToStringValueConverter : ValueConverter {
    public override object ConvertFromStorageType(object value) {
        return Convert.ToString(value) == "T";
    }
    public override object ConvertToStorageType(object value) {
        return Convert.ToBoolean(value) ? "T" : "F";
    }
    public override System.Type StorageType {
        get { return typeof(string); }
    }
}
See Also