Mukesh Mukesh - 1 year ago 96
C# Question

Entity Framework Code-First - Define the key for this EntityType

Hi I'm planning to test EF Code First in one of my project. This is what I want actually.
I have three tables and the structure is as follows

public partial class App_user
{
public int id { get; set; }
public string name { get; set; }
public string email_address { get; set; }
public string password { get; set; }
public int user_type { get; set; }
public List<Role> Roles { get; set; }
}

public partial class Role
{
public int id { get; set; }
public string name { get; set; }
}
public partial class User_role
{
public int user_id { get; set; }
public int role_id { get; set; }
public virtual Role Role { get; set; }
public virtual App_user App_user { get; set; }
}


In the third table there is no primary key. So it gives an error while running. Here is the error message -


System.Data.Edm.EdmEntityType: :
EntityType 'User_role' has no key
defined. Define the key for this
EntityType.
System.Data.Edm.EdmEntitySet:
EntityType: The EntitySet User_roles
is based on type User_role that has no
keys defined.


Why its is happening? Is there a solution for this?

Answer Source

If think you are trying to model many-to-many relation between user and role. In such case your model is completely wrong.

Use this instead:

public partial class App_user
{
    public int id { get; set; }
    public string name { get; set; }
    public string email_address { get; set; }
    public string password { get; set; }
    public int user_type { get; set; }
    public virtual ICollection<Role> Roles { get; set; }
}

public partial class Role
{
    public int id { get; set; }
    public string name { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

This will create many-to-many automatically and you will not need to bother with junction table. If you need to expose junction table you must use this:

public partial class App_user
{
    public int id { get; set; }
    public string name { get; set; }
    public string email_address { get; set; }
    public string password { get; set; }
    public int user_type { get; set; }
    public virtual ICollection<User_Role> UserRoles { get; set; }
}

public partial class Role
{
    public int id { get; set; }
    public string name { get; set; }
    public virtual ICollection<User_Role> UserRoles { get; set; }
}

public partial class User_role
{
    [Key, ForeignKey("App_user"), Column(Order = 0)]
    public int user_id { get; set; }
    [Key, ForeignKey("Role"), Column(Order = 1)]
    public int role_id { get; set; }
    public virtual Role Role { get; set; }
    public virtual App_user App_user { get; set; }
}

Exposing junction table is meaningless if you don't need additional properties in it.

To your error - each entity in Entity framework must have primary key defined.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download