POCO with Enum stored as NULL

ServiceStack version 4.5.14

It is my understanding that Enum will be stored as varchar(max).

I see that the table generated from the code first class is correctly reflected of each other.

What I do not see is the storage of the Enum property value.

The trimmed down class:

[Alias( "NonJobEvents" )]
public sealed class NonJobEvent
{
  [AutoIncrement]
  public int Id { get; set; }

 public Enum EventType { get; set; }
}

The excluded properties of the above class get properly stored in the database. Setting JsConfig.TreatEnumAsInteger = true makes no difference in the resulting output. The EventType property column is always NULL.

The EventType property gets set to values from a third party API, each enum value is assigned an integer. e.g. var e = new NonJobEvent { EventType = TrackingEvent.Login };

I’m looking for insight as to what I may not be seeing or doing.

By default Enum’s are stored as their String name, if you don’t specify an enum value it defaults to the Enum of default(Enum) which is behaving as expected where inserting a row without specifying an Enum, e.g:

public enum SomeEnum
{
    Value1,
    Value2,
    Value3
}

public class TypeWithEnum
{
    public int Id { get; set; }
    public SomeEnum EnumValue { get; set; }
}

LogManager.LogFactory = new ConsoleLogFactory();
using (var db = OpenDbConnection())
{
    db.DropAndCreateTable<TypeWithEnum>();

    var obj = new TypeWithEnum { Id = 1 };
    db.Insert(obj);
}

Will insert the value of default(SomeEnum):

DEBUG: SQL: DROP TABLE "TypeWithEnum"
DEBUG: SQL: CREATE TABLE "TypeWithEnum" 
(
  "Id" INTEGER PRIMARY KEY, 
  "EnumValue" VARCHAR(255) NOT NULL 
); 

DEBUG: SQL: INSERT INTO "TypeWithEnum" ("Id","EnumValue") VALUES (@Id,@EnumValue)
PARAMS: @Id=1, @EnumValue=Value1

If you’re seeing different behavior can you provide a complete example with logging that’s not working as expected?

I see also that the issue is happening while using the in memory database as well.

One of the unit tests in the linked solution archive will fail.

Your Enum Type needs to be the type of the Enum, not Enum, i.e:

public TestEnum EventType { get; set; }

Okay, this is not how I expected it to behave.

Why is this the case that the specific value type is required to define the property so that it can be stored as a string or an integer?

Take the following for example where both properties are of Enum : ValueType and are assigned value types, we’re easily able to determine both the type and the value.

internal enum TestEnum
{
    Value1 = 1,
    Value2 = 2
}
internal enum TestEnum2
{
    Value3 = 3,
    Value4 = 4
}

internal class BaseClassTest
{
    public Enum ValueType { get; set; }
    public Enum ValueType2 { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var foo = new BaseClassTest
        {
            ValueType = TestEnum.Value1,
            ValueType2 = TestEnum2.Value4
        };

        Console.WriteLine(foo.ValueType.GetType(  ));
        Console.WriteLine("{0}: {1:D}", foo.ValueType, foo.ValueType);
        Console.WriteLine(foo.ValueType2.GetType(  ));
        Console.WriteLine("{0}: {1:D}", foo.ValueType2, foo.ValueType2);
        Console.ReadKey( );
    }
}

You can’t use an unknown Enum Type as OrmLite needs to know the Type to dehyrdate the data into (from the raw string or integer value stored in the db), same goes for object, dynamic and other unknown types.

If you want to be able to store any enum value use a string or int property and have your App’s logic decode it into the correct enum when needed.

I had a feeling that’d be a probable cause. Thank you for explaining.

Hopefully this post will help someone else.

1 Like