【问题标题】:Entity Framework Code-First - Define the key for this EntityType实体框架代码优先 - 定义此 EntityType 的键
【发布时间】:2011-07-25 20:33:45
【问题描述】:

您好,我计划在我的一个项目中测试 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 没有 已定义键。

为什么会这样?有解决方案吗?

【问题讨论】:

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


    【解决方案1】:

    你可以这样做:

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

    【讨论】:

    • 这不会成为 user_id 的关键吗?如果用户有多个角色怎么办?
    • 类似的东西怎么样?
    • @YngveB.Nilsen 如何添加 [Key] 属性?我提到了 System.ComponentModel.DataAnnotation。但它只显示 [foreignkey] 是 [key] 在不同的目录下?
    • @omachu23 早在 2011 年(撰写此答案时)它在 System.ComponentModel.DataAnnotation 中,但今天是一个不同的问题 :)
    【解决方案2】:

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

    改用这个:

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

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

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

    【讨论】:

    • [Key, ForeignKey("App_user"), Column(Order = 0)] - 使用它的命名空间是什么?
    • System.ComponentModel.DataAnnotations(它也有单独的程序集)。
    • @LadislavMrnka,我似乎没有申请[Key, ForeignKey("App_user"), Column(Order = 0)],只有[Key]可用,我错过了什么?谢谢。
    • @autrevo:确保您引用的是 EntityFramework.dll。 .NET 4.0 不直接包含这些注释(.NET 4.5 包含)。
    • ForeignKey("") 并不是必需的。
    【解决方案3】:

    因为我使用了带有自动生成代码的 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());
    

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-02
        • 2011-08-05
        • 1970-01-01
        相关资源
        最近更新 更多