2011-03-30 25 views
24

Hola, estoy planeando probar EF Code First en uno de mis proyectos. Esto es lo que quiero en realidad. Tengo tres tablas y la estructura es la siguienteEntity Framework Code-First: defina la clave para este EntityType

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; } 
    } 

En la tercera tabla no hay ninguna clave primaria. Entonces da un error mientras se ejecuta. Aquí está el mensaje de error -

System.Data.Edm.EdmEntityType:: EntityType 'user_role' ha definido ninguna clave . Defina la clave para este EntityType. System.Data.Edm.EdmEntitySet: EntityType: EntitySet User_roles se basa en el tipo User_role que no tiene claves definidas.

¿Por qué está sucediendo? ¿Existe alguna solucion para esto?

Respuesta

37

Si piensa que está tratando de modelar muchos-a-muchos relación entre el usuario y el papel. En tal caso, su modelo es completamente incorrecto.

Use este lugar:

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; } 
} 

Esto creará muchos-a-muchos automáticamente y no tendrá que molestarse con tabla de unión. Si necesita para exponer tabla de unión debe utilizar esto:

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; } 
} 

La exposición de tabla de unión no tiene sentido si no es necesario propiedades adicionales en el mismo.

A su error: cada entidad en el marco de Entity debe tener definida la clave principal.

+1

[Key, ForeignKey ("App_user"), Column (Order = 0) ] - ¿Cuál es el espacio de nombre para usar con él? – Mukesh

+4

System.ComponentModel.DataAnnotations (también tiene un ensamblaje separado). –

+0

@LadislavMrnka, no parece aplicar '[Key, ForeignKey (" App_user "), Column (Order = 0)]', solo [Key] está disponible, ¿qué me estoy perdiendo? Gracias. – Abhijeet

15

Usted puede simplemente hacer como esto:

public partial class User_role 
{ 
    [Key] 
    public int user_id { get; set; } 
    [Key] 
    public int role_id { get; set; } 
    public virtual Role Role { get; set; } 
    public virtual App_user App_user { get; set; } 
} 
+0

no habría que hacer llave user_id? ¿Qué pasa si el usuario tiene muchos roles? – archil

+0

¿Qué tal algo así? –

+0

@ YngveB.Nilsen ¿cómo se agrega la propiedad [Key]? Remití System.ComponentModel.DataAnnotation. Pero solo muestra [tecla externa] es [tecla] bajo un directorio diferente? – CodeEngine

1

porque he usado un modelo de datos Entiry ADO.net con código generado automatizado que no querían cambiar el modelo de clases así que cambié los WebApiConfig.cs para definir las claves de los modelos subyacentes:

ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); 
EntitySetConfiguration<Registration> EntitySetConfiguration_Registration = builder.EntitySet<Registration>("Registration"); 
EntitySetConfiguration<Lead> EntitySetConfiguration_Lead = builder.EntitySet<Lead>("Lead"); 
EntitySetConfiguration<Session> EntitySetConfiguration_Session = builder.EntitySet<Session>("Session"); 
EntitySetConfiguration_Registration.EntityType.HasKey(p => p.Registration_Id); 
EntitySetConfiguration_Lead.EntityType.HasKey(p => p.Lead_Id); 
EntitySetConfiguration_Session.EntityType.HasKey(p => p.Session_Id); 
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel()); 
0

asegurarse de que está utilizando (usando System.ComponentModel.DataAnnotations;)

sólo tiene que añadir la palabra clave [Key] en la parte superior del campo de datos en el modelo

Cuestiones relacionadas