Entity Framework Code-First - определите ключ для этого EntityType - PullRequest
25 голосов
/ 30 марта 2011

Привет, я планирую протестировать 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' не определен ключ.Определите ключ для этого EntityType.System.Data.Edm.EdmEntitySet: EntityType: EntitySet User_roles основан на типе User_role, для которого не определены ключи.

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

Ответы [ 4 ]

37 голосов
/ 30 марта 2011

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

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

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

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

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

18 голосов
/ 30 марта 2011

Вы можете просто сделать так:

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; }
}
1 голос
/ 30 марта 2014

Поскольку я использовал модель данных ADO.net Entiry с автоматически сгенерированным кодом, я не хотел менять классы модели, поэтому я изменил файл 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());
0 голосов
/ 23 мая 2017

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

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

...