TValueConverterFactory does not return a converter for a Nullable<EnumType>

Issue #207 resolved
Todd Flora
created an issue

We have the following type defined:

  TDocumentItemType = (
    ditNone,    //none
    ditSale,    //Sale
    ditReturn,  //Return
    ditOrder,   //Order
    ditExchange, //Exchange
    ditVoid      //Item was voided

And then a Field in one of our ORM Model files as follows:

    FItemType: Nullable<TDocumentItemType>;

When the ORM attempts to read the data and convert it the following error occurs:


It would seem that it is valid to have a Nullable Enumerated type as the database can certaintily have no value.

After tracing into the code it seems that the TValueConverterFactory does not return a Converter for a Nullable<TEnumType> type.

Is it possible to add a converter for nullable enum types.

Fails here with no converter.

function TDefaultConverter.TryConvertToParam(const value: TValue;
  const targetTypeInfo: PTypeInfo;
  out targetValue: TValue;
  const parameter: TValue): Boolean;
  converter: IValueConverter;
  converter := TValueConverterFactory.GetConverter(value.TypeInfo, targetTypeInfo);
  Result := Assigned(converter)
    and converter.TryConvertTo(value, targetTypeInfo, targetValue, parameter);
  if not Result then
    // workaround for wrong TValue.TryCast for string to float (it calls ConvStr2Str by mistake)
    if not ((value.Kind in [tkString, tkLString, tkWString, tkUString])
      and (targetTypeInfo.Kind = tkFloat)) then
    Result := value.TryCast(targetTypeInfo, targetValue);

Comments (10)

  1. Todd Flora reporter

    So I write a test for this to hopefully help you see the issue. Into the Spring.Tests.ValueConverters unit TTestFromInteger fixture.

    procedure TTestFromInteger.TestIntegerToNullableEnum;
      outValue: TValue;
      outNullable: Nullable<TEnumeration>;
      outValue := fConverter.ConvertTo(TValue.From<Integer>(1),
      CheckEquals(1, Integer(outNullable.Value));
  2. Stefan Glienke repo owner

    Look into Spring.ValueConverters.pas - there are multiple converters for nullable to inner type and vice versa and integer<->enum. You just need one for integer <-> nullable<enum>. The trick however will be the correct registration if you want to make it for all nullable enums in general and not for each enum type explicitly. But I guess you'll figure it out.

  3. Log in to comment