您好我打算在我的一个项目中测试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没有 键定义。
为什么会这样?这有解决方案吗?
答案 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]