2011-03-30 154 views
24

嗨,我打算在我的一個項目中測試EF代碼優先。這是我想要的。 我有三個表和結構如下實體框架代碼優先 - 爲此實體類型定義密鑰

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類型。

它爲什麼會發生?有沒有解決方案?

回答

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

[Key,ForeignKey(「App_user」),列(Order = 0) ] - 與它一起使用的命名空間是什麼? – Mukesh 2011-03-30 07:46:44

+4

System.ComponentModel.DataAnnotations(它也有單獨的程序集)。 – 2011-03-30 10:19:36

+0

@LadislavMrnka,我似乎不應用'[Key,ForeignKey(「App_user」),Column(Order = 0)]',只有[Key]可用,我錯過了什麼?謝謝。 – Abhijeet 2012-12-13 05:39:52

15

您可以簡單地這樣做:

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

不會使user_ID的關鍵?如果用戶有很多角色呢? – archil 2011-03-30 07:27:44

+0

那樣的事情呢? – 2011-03-30 07:46:39

+0

@ YngveB.Nilsen你如何添加[Key]屬性?我引用System.ComponentModel.DataAnnotation。但它只顯示[foreignkey]是在不同的目錄下的[key]? – CodeEngine 2015-05-11 18:40:20

1

因爲我使用的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

確保您使用(使用System.ComponentModel.DataAnnotations;)

只是在數據字段的頂部添加關鍵字[關鍵]示範