5

I am using EF5 and .NET 4.5. I have one particular class that is being generated incorrectly in the database. Although it is somewhat more complicated in my website, I'll simplify;

namespace Store.Enities
{
    public enum Role
    { Manager, Clerk }

    public class User
    {
        public int Id {get; set;}
        public ICollection<Role> Roles {get; set;}
    }

    public class StoreContext : DbContext
    {
        public DbSet<User> Users {get; set;}

        public StoreContext()
        {
            Database.SetIntializer(new DropCreateDatabaseIfModelChanges<StoreContext>());
        }
    }
}

As you can see a user can have more than one role. For some reason I can't manage to store the roles in the database.

CharlesB
  • 86,532
  • 28
  • 194
  • 218
user2008934
  • 321
  • 2
  • 9

3 Answers3

10

An enum is still a primitive type, in particular an integer. Just as your User class can't have an ICollection<int> that maps to something in the database, it can't have a collection of the enum.

You should define a Role class that could look like this:

public class Role
{
    public int Id {get; set;}
    public Roles Role {get; set;}
}

And change the name of the enum into Roles (or anything but Role).

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
6

I am still running Windows XP SP3 so i can't install .NET Framework 4.5 and i can't run a test to see what's wrong but i can guess. In your design each "User" may have zero-to-many "Roles", now by convention Entity Framework would generate a foreign key on "Roles" to reference "Users" but since "Role" is an enumeration which is a Complex Object (Value Object) entity framework doesn't support this situation, "Entity Framework doesn't support having a collection of a Complex Type on an Entity type", you need to make Role an entity and give it an ID. Just to be sure i am correct try making the relation one-to-one (each user has only one role) and if it worked then i am right.

Ibrahim Najjar
  • 19,178
  • 4
  • 69
  • 95
1

Based on the answer by Gert Amold you could create a nice wrapper class by using the implicit operator:

public class RoleWrapper
{
    public int Id { get; set; }

    // Role is any Enum
    public Role Role { get; set; }

    public static implicit operator Role(RoleWrapper val)
    {
        return val.Role;
    }
    public static implicit operator RoleWrapper(Role val)
    {
        return new RoleWrapper() { Role = val };
    }
}

This way you can use the collection with the primitiv Enum type Role:

myUser.Roles.Add(Role.WhateverRole);
Role firstRole = myUser.Roles[0];
Sam
  • 1,301
  • 1
  • 17
  • 26