2014-02-05 15 views
2

我有一個需要它的Id列被綁定到另一個表,和第3表格其(Id, Code)列的表。我可以輕鬆地在SQL Server中同時使用主鍵和唯一索引,但不知道如何在實體框架中實現它。實體框架:複合外鍵上唯一的(沒有主鍵)母公司領域

如果我把兩列[Key]屬性,那麼我無法創建的第一關係。

否則,如果我只應用一個[Key]話,我不能讓第二個關係。

有什麼解決方法嗎?

回答

2

好的,我能夠使用Fluent API製作儘可能多的按鍵。它現在有效。

更詳細:
在業務方面,我有三個字段,就像HTML文檔中Form對象 - 的類型input, choice, text, radiogroup
我prefere存儲字段的數據強類型,在不同的表,但表單需要知道哪些字段可以保持其唯一順序。

所以在數據庫中,我有表:

Form - 包含窗體的名稱和說明
FormField - (0到許多行對每個表單)中包含FormId的FieldTypeOrderNo。通過將(FormId,OrderNo)設置爲唯一,我維護正確的順序。

的訣竅是,輸入的字段itselves存儲在不同的表像InputFieldChoiceFieldNumberField等。我希望他們被束縛於母公司FormField行像0或1比1,不要讓他們迷失方向父行被刪除時。
如果它是簡單的親子關係,我可以使用標準的FK,但在這裏我有variuos子表。

使這一切吻合,SQL服務器在我創建了一個複合PK (FormId,的FieldType)FormField表和FKS爲(FormId,的FieldType)在所有子表,其中FieldType被設定爲恆定計算值(在表ChileField等說在InputField表0,1)。
因此,我已經有了一個良好的親子約束單個FormField和多個子特定類型的表。
在EF方法,使複合FK所有你需要的相應字段是鑰匙,所以你穿上這兩個領域[鍵]屬性。
但是,如果您的類型特定表需要自己的子項(如ChoiceField有其ChoiceOptions),並且您已經有一個組合鍵,那麼您需要使用現有的組合鍵或添加一個新的鍵集(只有ID字段)。

所以,我的問題是使ChoiceField表有兩組鍵,其中一個是父FieldForm行的複合鍵,第二個是ChoiceOption子表的簡單鍵。
使用Fluent API我能夠添加第二個鍵。

這是我的EF模型:

[Table("Form")] 
public class Form : IEntity 
{ 
    [Key, Column("FormID")] 
    public int Id { get; set; } 

    [Required, StringLength(50)] 
    public string Name { get; set; } 

    public ICollection<FormField> FormFields { get; set; } 
} 

[Table("FormField")] 
public class FormField : IEntity 
{ 
    [Key, Column("FormFieldID", Order = 0)] 
    public int Id { get; set; } 

    [Key, Column(Order = 1)] 
    public FieldType FieldType { get; set; } 

    [ForeignKey("Form")] 
    public int FormId { get; set; } 

    public int OrderNo { get; set; } 

    public virtual Form Form { get; set; } 

    public virtual AddressField AddressField { get; set; } 
    public virtual ChoiceField ChoiceField { get; set; } 
    public virtual DateTimeField DateTimeField { get; set; } 
// etc 
} 

[Table("ChoiceField")] 
public class ChoiceField : BaseField, IEntity 
{ 
    [Key, ForeignKey("FormField"), Column("FormFieldID", Order = 0)] // these keys are for parent FormField table 
    public int Id { get; set; } 

    [Key, ForeignKey("FormField"), Column(Order = 1)] 
    public FieldType FieldType { get; set; } 

    public virtual FormField FormField { get; set; } 

    public ICollection<ChoiceFieldOption> ChoiceFieldOptions { get; set; } 
} 

[Table("ChoiceFieldOption")] 
public class ChoiceFieldOption : IEntity 
{ 
    [Key, Column("ChoiceFieldOptionID")] 
    public int Id { get; set; } 

    [ForeignKey("ChoiceField")] // this FK are bound to simple ChoiceField.Id key defined in fluent API 
    public int ChoiceFieldId { get; set; } 

    [Required, StringLength(50)] 
    public string Option { get; set; } 

    public int OrderNo { get; set; } 

    public virtual ChoiceField ChoiceField { get; set; } 
} 

...

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 

     modelBuilder.Entity<Form>(); 
     var eFormField = modelBuilder.Entity<FormField>(); 

     var eChoiceField = modelBuilder.Entity<ChoiceField>(); 

    // here I add a second Key for ChoiceField table 
     eChoiceField.HasKey(cf => new { cf.Id }); 

     var eChoiceFieldOption = modelBuilder.Entity<ChoiceFieldOption>(); 

     modelBuilder.Entity<AddressField>(); 
     modelBuilder.Entity<DateTimeField>(); 
    // ... 
    } 
+0

也許你可以詳細的答案,以顯示你的代碼最終使用來解決這個問題? – julealgon

+0

沒問題,在幾分鐘內 – LINQ2Vodka

+0

@julealgon現在可以嗎? :) – LINQ2Vodka