2011-11-01 66 views
1

我有一個簡單的1:許多聚合關係,讓說:EF 4.1代碼第一:如何從父指子記錄在一個一對多的關係

public class Parent 
{ 
    public string Name {get; set;} 
    public Child SelectedChild {get; set;} 
    public Child PublishedChild {get; set;} 
    public virtual ICollection<Child> AllChildren {get; set;} 
} 

public class Child 
{ 
    public string Name {get; set;} 
    [Required] 
    public Parent Father {get; set;} 
} 

當創建此架構模型我得到的錯誤:

在表'父'上引入FOREIGN KEY約束'Parent_SelectedChild'可能會導致循環或多個級聯路徑。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY約束

所以我以下內容添加到OnModelCreating:

 modelBuilder.Entity<Child>() 
      .HasRequired(v => v.Parent) 
      .WithOptional(c => c.SelectedChild) 
      .WillCascadeOnDelete(false); 

     modelBuilder.Entity<Child>() 
      .HasRequired(v => v.Parent) 
      .WithOptional(c => c.PublishedChild) 
      .WillCascadeOnDelete(false); 

這得到全面原來的錯誤,但我現在得到:

無法確定'xxx.Parent_SelectedChild'關係的主體結尾。 多個添加的實體可能具有相同的主鍵。

任何人都可以幫忙嗎? 我基本上想要做的就是引用來自父級的1:多聚合關係上的特定子記錄。我假設EF會在父級上創建INT子級id列,例如SelectedChild_Id & PublishedChild_Id(或類似)。

在此先感謝 -macon

編輯:針對@Slauma: 我可以使用生成的架構:

  modelBuilder.Entity<Parent>() 
      .HasOptional(p => p.SelectedChild) 
      .WithOptionalPrincipal() 
      .WillCascadeOnDelete(false); 

     modelBuilder.Entity<Parent>() 
      .HasOptional(p => p.PublishedChild) 
      .WithOptionalPrincipal() 
      .WillCascadeOnDelete(false); 

     modelBuilder.Entity<Parent>() 
      .HasMany(p => p.AllChildren) 
      .WithRequired(c => c.Father) 
      .WillCascadeOnDelete(false); 

但是,這對孩子的記錄生成多個FK例如Parent_Id,Parent_Id1。我只想從Parent的引用到其中一個子行,例如Parent_SelectedChildId。我必須手動使用父列上的int列進行此操作嗎?

回答

2

我覺得你有三個1對多的關係:

modelBuilder.Entity<Parent>() 
    .HasOptional(p => p.SelectedChild) 
    .WithMany() 
    .WillCascadeOnDelete(false); 

modelBuilder.Entity<Parent>() 
    .HasOptional(p => p.PublishedChild) 
    .WithMany() 
    .WillCascadeOnDelete(false); 

modelBuilder.Entity<Parent>() 
    .HasMany(p => p.AllChildren) 
    .WithRequired(c => c.Father) 
    .WillCascadeOnDelete(false); 

編輯

我測試過我上面的映射與正是ParentChild類,你在你的提供問題 - 唯一的例外是我已經爲這兩個類添加了主鍵屬性:public int Id { get; set; }。否則,EF會抱怨缺少關鍵屬性。此映射不拋出異常,並在數據庫中創建下表:

家長表:

- Id     int    not nullable (PK) 
- Name     nvarchar(MAX) nullable 
- SelectedChild_Id  int    nullable (FK) 
- PublishedChild_Id  int    nullable (FK) 

兒童表:

- Id     int    not nullable (PK) 
- Name     nvarchar(MAX) nullable 
- Father_Id    int    not nullable (FK) 

因此,也有預期三個外鍵列。

由於您根據您的評論得到了一個異常,我猜測您在測試的代碼中實際上存在一些重要差異。

順便說一句:將Parent類的兩個導航屬性映射爲一對一關係要困難得多,如果不是不可能的話。在EF中,您需要兩個表之間共享的主鍵來映射一對一關係,因此不能將兩個不同的實體分配給兩個導航屬性,因爲它們不能同時具有與父鍵相同的鍵。

+0

感謝您的回覆。但那不行。我剛剛得到:在模型生成過程中檢測到一個或多個驗證錯誤: \t System.Data.Edm.EdmAssociationType::多重性與'Parent_SelectedChild_Target'關係'Parent_SelectedChild'中的參照約束衝突。由於從屬角色中的所有屬性都是不可空的,所以主體角色的多重性必須爲'1'。 – macon

+0

請參閱上面的編輯到原始問題的進度。 – macon

+0

@macon:我在上面的答案中添加了一個編輯部分。 – Slauma