web-dev-qa-db-fra.com

Entity Framework Code-First - Définissez la clé pour ce type d'entité

Bonjour, je prévois de tester EF Code First dans l’un de mes projets. C'est ce que je veux réellement. J'ai trois tables et la structure est la suivante

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

Dans la troisième table, il n'y a pas de clé primaire. Donc, cela donne une erreur en cours d'exécution. Voici le message d'erreur - 

System.Data.Edm.EdmEntityType:: EntityType 'User_role' n'a pas de clé défini. Définissez la clé pour cela Type d'entité. System.Data.Edm.EdmEntitySet: EntityType: les rôles d'utilisateur EntitySet est basé sur le type User_role qui n'a pas clés définies.

Pourquoi ça se passe? Y a-t-il une solution pour cela? 

25
Mukesh

Si vous pensez que vous essayez de modéliser une relation plusieurs à plusieurs entre l'utilisateur et le rôle. Dans ce cas, votre modèle est complètement faux.

Utilisez ceci à la place:

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

Cela créera automatiquement plusieurs-plusieurs et vous n'aurez pas besoin de vous soucier de la table de jonction. Si vous avez besoin d'exposer une table de jonction, vous devez utiliser ceci:

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

Exposer une table de jonction n'a pas de sens si vous n'avez pas besoin de propriétés supplémentaires. 

À votre erreur - chaque clé du framework Entity doit avoir une clé primaire définie.

37
Ladislav Mrnka

Vous pouvez simplement faire comme ça: 

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; }
}
18
Yngve B-Nilsen

Comme j'ai utilisé un modèle de données ADO.net Entiry avec un code généré automatiquement, je ne souhaitais pas modifier les classes de modèle. J'ai donc modifié WebApiConfig.cs pour définir les clés des modèles sous-jacents:

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());
1
LiQuick.net

assurez-vous que vous utilisez (en utilisant System.ComponentModel.DataAnnotations;)

ajoutez simplement le mot clé [Key] en haut du champ de données dans le modèle

0
Nelson