实体框架代码优先 - 定义此EntityType的密钥

时间:2011-03-30 06:25:10

标签: c# entity-framework ef-code-first entity-framework-4.1

您好我打算在我的一个项目中测试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 个答案:

答案 0 :(得分:37)

如果您认为您正在尝试模拟用户和角色之间的多对多关系。在这种情况下,你的模型是完全错误的。

请改用:

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

如果您不需要其他属性,则公开联结表是没有意义的。

您的错误 - 实体框架中的每个实体都必须定义主键。

答案 1 :(得分:18)

您可以这样做:

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

答案 2 :(得分:1)

因为我使用ADO.net全数据模型和自动生成的代码,所以我不想更改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());

答案 3 :(得分:0)

确保您正在使用(使用System.ComponentModel.DataAnnotations;)

只需在模型

中的数据字段顶部添加关键字[Key]