10

On an ASP.NET application I have a flag enum as follows:

[Flags]
enum Target : int {
  None = 0,
  Group = 1,
  Student = 2,
  Professor = 4,
  All = Group | Student | Professor
}

Can I save a value containing more than one item in a SQL Database Table using Entity Framework 6?

How would that be saved?

Thank You, Miguel

Miguel Moura
  • 36,732
  • 85
  • 259
  • 481

3 Answers3

18

To put things really simple, flags can be seen as an int sum (just to be simple but actually they work with bitwise operations).

So, for your case (provided enum), if a record has two targets (Student and Professor), the final result will be 6.

EF will store just this. 6. You have already told that EF should store this column as an INT because you've said that the enum should be understood as an int here:

enum Target : int {

There is no need to do anything (absolutely anything!) else.

To get this back into both Student and Professor, there is an Enum.Parse that you can call manually (only when needed) but EF will also populate the property with this already converted.

On your code, you'll have to worry just about the code. So, for instance, you can do:

var item = new Something() { Prop = Target.Student | Target.Professor };
context.Save();

var item2 = context.GetSomething();

if (item2.Prop.HasFlag(Target.Professor) && item2.Prop.HasFlag(Target.Student))
{
   // WOW!
}

That's just it. I'm using this with EF6 and there is no configuration at all. At least with CodeFirst approach.

But don't forget that this will work only with newer versions of .NET framework. Take a look into the Enum support topic from EF docs.

Anderson Matos
  • 3,132
  • 1
  • 23
  • 33
  • What happens when you have more than 32 flags in the enum? You'd overflow the int datatype. What is the recommended way then? string storage, to store an arbitrarily large number? – Russell Uhl Jan 19 '18 at 20:03
  • Changing to a long will increase combinations but you'll be very limited still (64 values). Flags are meant to be small. If you need larger combinations, you'll have to review your design (use a flags combination, change to a table, etc). Review this other question: https://stackoverflow.com/questions/1060760/what-to-do-when-bit-mask-flags-enum-gets-too-large – Anderson Matos Jan 23 '18 at 15:00
  • Yeah, I decided to go with a BitArray. Thank you! – Russell Uhl Jan 23 '18 at 18:10
3

You can save a combination of flags as an int:

int myFlags = (int)(Target.Group | Target.Professor);
Alberto
  • 15,626
  • 9
  • 43
  • 56
  • But how do I map that model property to EF column? Do I need to specify that is an Enum with Flags? – Miguel Moura Jan 09 '14 at 14:11
  • The only case where I can say this will be useful is when you have thousands of enums on the same entity and that might get slow to map. But for this, EF should not be used at all so there is no need to manually map into an INT column and back from it. – Anderson Matos Jan 09 '14 at 15:51
  • @MDMoura you only need to specify a column of type int – Alberto Jan 09 '14 at 16:09
  • @MiguelMoura Ignore the enum property and map to a backing property of type int – Mihai Bratulescu Sep 03 '20 at 14:31
0

The only difference between enum types with and without HasFlagAttribute is how they are written when using .ToString() (and maybe how they are parsed when using Enum.Parse). EF internally strips the information about enum type and is only using the underlying enum type (accounting for nullability).

Pawel
  • 31,342
  • 4
  • 73
  • 104