26

嗨,我计划在我的一个项目中测试 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

4 回答 4

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

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

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

于 2011-03-30T07:32:27.153 回答
19

你可以简单地这样做:

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; }
}
于 2011-03-30T07:18:10.100 回答
1

因为我使用了带有自动生成代码的 ADO.net 完整数据模型,所以我不想更改模型类,所以我更改了 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());
于 2014-03-30T11:04:12.693 回答
0

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

只需在模型的数据字段顶部添加关键字 [Key]

于 2017-05-23T09:14:13.503 回答