ServiceStack.OrmLite: StringLengthAttribute.MaxTex

2019-08-28 01:37发布

问题:

Using ServiceStack's OrmLite and decorating a Property with the following attribute, creates a column of type LONGTEXT, instead o TEXT as noted in the docs:

But it becomes LONGTEXT:

I tried setting the StringLenghtAttribute to something else, 65535, 70000, Int32.MaxValue etc, but it either interpretet it as a VARCHAR and gave me the Column length too big or Row size too large, or it became a LONGTEXT.

Question is: how can I force it to become "TEXT" (or any other text type in mysql)?

I could perhaps modify the MaxColumnDefinition and set it to TEXT but then I will never get LONGTEXT I assume.

UPDATE Setting the MaxColumnDefinition to TEXT didnt change a thing

Can I decorate the class with an attribute, specifying the type somehow? Or is that too sql-version-specific?

Or perhaps I should override the GetColumnDefinition and implement my own logic...

回答1:

(Please note that this solution produces other problems that I will ask in a separate SO post)

After some more research, it was solved creating my own StringConverter, as can be seen below:

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";
        }
    }
}

I also suggest setting the default StringLength to something smaller than the default 8000:

StringConverter converter = OrmLiteConfig.DialectProvider.GetStringConverter();
converter.StringLength = 255;

This way, the default string will be varchar(255). If you want to make a specific string property something else, then set the attribute according to the MyStringConverter:

type = typeof(tWorks.Core.CoreCommons.ContactModuleProtocols.SMS.ModuleSettingsSMS);
type.GetProperty(nameof(MyClass.Prop1)).AddAttributes(new StringLengthAttribute(255)); // ==> varchar(255)
type.GetProperty(nameof(MyClass.Prop2)).AddAttributes(new StringLengthAttribute(500)); // ==> TEXT
type.GetProperty(nameof(MyClass.Prop3)).AddAttributes(new StringLengthAttribute(70000)); // ==> LONGTEXT