Confusion about how Enums are actually stored.

441 views
Skip to first unread message

Stacey

unread,
Jan 15, 2013, 5:56:57 PM1/15/13
to rav...@googlegroups.com
In a project that uses enums, so using a mock example..

public enum Animals {
    Chihuahua,
    Kitten,
    Llama,
    Elephant,
    Badger,
    Mushroom
}
So let us assume I have an object that accepts this type as a property. So far so good. 

public class Cage {
    public Animal Animal { get; set; }
}
(This is a fake example of course).

So the following object


var cage = new Cage {
    Animal = Animal.Mushroom
}
Appears in Raven's management UI like this.


{
 "Animal" : "Mushroom"
}
But when I do a deserialize and convert it to JSON using the following code...


/// <summary>
/// Allows for any object to be serialized into Json very quickly.
/// </summary>
public static class JsonExtensions {
    /// <summary>
    /// Serializes an object to Javascript Object Notation.
    /// </summary>
    /// <param name="item">The item to serialize.</param>
    /// <returns>
    /// The item serialized as Json.
    /// </returns>
    public static string ToJson(this object item) {
        return Newtonsoft.Json.JsonConvert.SerializeObject(item);
    }
}
I get the following output...

{
 "Animal" : "5"
}
So can someone clarify what is happening here? Are these stored in Raven by an integer or a string? If I were to re-arrange the order of the enum, would it suddenly fail? Is the number generated just because of the deserialization or is it actually saved as a number and Raven is doing some kind of magic on the UI end?

Paul Hinett

unread,
Jan 15, 2013, 6:08:43 PM1/15/13
to rav...@googlegroups.com
Raven stores them as strings i believe.

It's the default settings of the Json serializer to convert enums to
integers, I *think* you can override this though.
> of the *deserialization* or is it actually *saved* as a number and

Matt Johnson

unread,
Jan 15, 2013, 8:02:44 PM1/15/13
to ravendb
Correct. Without being told otherwise, Json.Net will store enums as
integers. But Raven specifically tells Json.Net to store enums as
strings as part of its default conventions.

You can easily change this behavior with the following:

documentStore.Conventions.SaveEnumsAsIntegers = true;

But personally, I don't recommend it. You lose readability in your
documents, and the only thing you really gain is ability to rename
them - which shouldn't happen very often with enums anyway.

Maybe the only case for non-string enums is with enums that use the
[Flags] attribute. But be aware that compound values are NOT
queryable in the ways you would expect from regular defined values.

georgiosd

unread,
Jan 16, 2013, 3:46:11 AM1/16/13
to rav...@googlegroups.com
Yes, Enum.HasFlag is not supported.

So there's no way to query for a field enum?

Oren Eini (Ayende Rahien)

unread,
Jan 16, 2013, 3:47:46 AM1/16/13
to ravendb
You can query for the value, but not for the flags.

georgiosd

unread,
Jan 16, 2013, 3:52:39 AM1/16/13
to rav...@googlegroups.com
Would that be worth supporting? 
If there was a way to force JSON.NET to serialize fields as integers instead of strings, the operation would be really cheap, I guess?

Oren Eini (Ayende Rahien)

unread,
Jan 16, 2013, 5:17:48 AM1/16/13
to rav...@googlegroups.com
We have SaveEnumsAsIntegers

Georgios Diamantopoulos

unread,
Jan 16, 2013, 6:24:21 AM1/16/13
to rav...@googlegroups.com
AFAIK that applies to all enums, not fields only though


Date: Wed, 16 Jan 2013 11:17:48 +0100
Subject: Re: [RavenDB] Confusion about how Enums are actually stored.
From: aye...@ayende.com
To: rav...@googlegroups.com

Oren Eini (Ayende Rahien)

unread,
Jan 16, 2013, 6:30:47 AM1/16/13
to ravendb
Yes

Stacey Thornton

unread,
Jan 16, 2013, 1:50:58 PM1/16/13
to rav...@googlegroups.com

I actually want to store them as strings. I just wanted to make sure that if I rearrange them or add new values it won't break. If it stores as strings, then I can't see why it would break.

Chris Marisic

unread,
Jan 16, 2013, 3:13:19 PM1/16/13
to rav...@googlegroups.com
The strings can't be renamed. If you rename, you will need to either update all your existing data or you will need to use document conversion listeners.

Stacey

unread,
Jan 16, 2013, 3:18:57 PM1/16/13
to rav...@googlegroups.com
I don't entirely understand. If Raven stores it outright as a string, wouldn't it search for the matching enum value when it deserializes? So the order isn't relevant.

I am more interested in "rearranging" than "renaming", but let's say ..

public enum Animals {
    Turtle,
    Frog,
    Snake
}

And I create a bunch of objects. Now for (whatever reason) the enum changes to 

public enum Animals {
    Frog,
    Snake,
    Turtle
}

if the enums were stored as strings, how would this cause a problem?

I'm unfamiliar with document listeners.

Oren Eini (Ayende Rahien)

unread,
Jan 16, 2013, 3:39:45 PM1/16/13
to ravendb
The idea is that you used to have:

public enum Animals {
    Turtle,
    Frog,
    Snake
}

And you changed it to:

public enum Animals {
    Turtle,
    Toad,
    Snake
}

that would cause an issue

Stacey

unread,
Jan 16, 2013, 4:00:35 PM1/16/13
to rav...@googlegroups.com
So then what would you do if you had a need to update enums for some reason?

Oren Eini (Ayende Rahien)

unread,
Jan 16, 2013, 4:03:20 PM1/16/13
to ravendb
Use patch to fix the values.

Georgios Diamantopoulos

unread,
Jan 16, 2013, 4:10:20 PM1/16/13
to rav...@googlegroups.com, ravendb
In case you didnt notice, in Orens example he renamed Frog to Toad. Just changing the order wont break anything

Sent from my iPad
Reply all
Reply to author
Forward
0 new messages