Подтвердить что ты не робот

Entity Framework Code-First - определение ключа для этого EntityType

Привет, я планирую протестировать EF Code First в одном из моих проектов. Это то, чего я хочу на самом деле. У меня три таблицы, и структура выглядит следующим образом

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

В третьей таблице нет первичного ключа. Таким образом, он дает ошибку во время работы. Вот сообщение об ошибке -

System.Data.Edm.EdmEntityType:: EntityType 'User_role' не имеет ключа определены. Определите ключ для этого Тип объекта. System.Data.Edm.EdmEntitySet: EntityType: EntitySet User_roles основан на типе User_role, который не имеет Определены ключи.

Почему это происходит? Есть ли решение для этого?

4b9b3361

Ответ 1

Если вы думаете, что пытаетесь моделировать отношение "многие ко многим" между пользователем и ролью. В таком случае ваша модель полностью ошибочна.

Используйте это вместо:

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

Это автоматически создаст много-ко-многим, и вам не придется беспокоиться о таблице соединений. Если вам нужно открыть таблицу соединений, вы должны использовать это:

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

Отображение таблицы соединений бессмысленно, если вам не нужны дополнительные свойства.

К вашей ошибке - каждый объект в структуре Entity должен иметь определенный первичный ключ.

Ответ 2

Вы можете просто сделать следующее:

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

Ответ 3

Поскольку я использовал ADO.net Entiry Data Model с автоматизированным сгенерированным кодом, я не хотел менять классы модели, поэтому я изменил WebApiConfig.cs, чтобы определить ключи базовых моделей:

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());

Ответ 4

убедитесь, что вы используете (используя System.ComponentModel.DataAnnotations;)

просто добавьте ключевое слово [Key] в верхней части поля данных в Model