Search code examples
mysqlblobservicestackormlite-servicestack

ServiceStack.OrmLite: Implementing custom StringConverter affects column type of complex BLOB fields


In a previous SO question I asked how I change the MySql column type when I have string properties in my POCOs.

The answer, which I answered myself, was to implement my own StringConverter. It was sort of an acceptable approach, I thought.

However, in my answer, I noted that not only was my string properties affected, so was all those properties that are complex and where OrmLite BLOBs them as JSON.

The field types for those complex columns in MySQL also became like varchar(255), which of course doesn't last very long.

The StringConverter was very short and easy:

  • I said that default string length is 255:
StringConverter converter = OrmLiteConfig.DialectProvider.GetStringConverter();
    converter.StringLength = 255;
  • I wanted string props defined as 255 chars or smaller to be varchar(255)
  • string props defined as > 255 and < 65535 to be text
  • string props defined as >= 65535 to be longtext

MyStringConverter:

public class MyStringConverter : StringConverter
{
    public override string GetColumnDefinition(int? stringLength)
    {
        if (stringLength.GetValueOrDefault() == StringLengthAttribute.MaxText)
            return MaxColumnDefinition;

        if (stringLength.GetValueOrDefault(StringLength) <= 255)
        {
            return UseUnicode
            ? $"NVARCHAR({stringLength.GetValueOrDefault(StringLength)})"
            : $"VARCHAR({stringLength.GetValueOrDefault(StringLength)})";
        }
        else if (stringLength.GetValueOrDefault(StringLength) <= 65535)
        {
            return $"TEXT";
        }
        else
        {
            return "LONGTEXT";
        }
    }
}

But, as stated above, a property that looks like this (ActionInfo just contains some strings and List):

public List<ActionInfo> _AvailableActions { get; set; }

produced a table like this when using MyStringConverter:

enter image description here

Without using MyStringConverter, the column became a longtext.

Question is then: what am I missing? I still want complex, BLOBed fields to become longtext so that JSON BLOBing can be done. I was hoping that the StringConverter only affected string properties?


Solution

  • The column definition of blobbed complex types should use the ReferenceTypeConverter which by default resolves to DialectProvider.GetStringConverter().MaxColumnDefinition;

    You should inherit the RDBMS-specific MySqlStringConverter if you want to change the string behavior of MySQL Strings otherwise you will revert back to inheriting generic RDBMS behavior which uses VARCHAR(8000) for strings and MaxColumnDefinition.

    Alternatively you can override MaxColumnDefinition in your own String converter:

    public override string MaxColumnDefinition => "LONGTEXT";