2011-04-29 142 views
31

我將在具有外鍵的Employee和Team實體之間創建兩個引用。 所以我定義了兩個實體遵循實體框架4.1 InverseProperty屬性和ForeignKey

public class Employee 
{ 
    public int EmployeeId { get; set; } 
    public string Name { get; set; } 

    [ForeignKey("FirstTeam")] 
    public int FirstTeamId { get; set; } 

    [InverseProperty("FirstEmployees")] 
    public virtual Team FirstTeam { get; set; } 

    [ForeignKey("SecondTeam")] 
    public int SecondTeamId { get; set; } 

    [InverseProperty("SecondEmployees")] 
    public virtual Team SecondTeam { get; set; } 
} 

public class Team 
{ 
    public int Id { get; set; } 
    public string TeamName { get; set; } 

    [InverseProperty("FirstTeam")] 
    public virtual ICollection<Employee> FirstEmployees { get; set; } 

    [InverseProperty("SecondTeam")] 
    public virtual ICollection<Employee> SecondEmployees { get; set; } 
} 

我認爲這在理論上是正確的,但它顯示了異常如下:

{"Introducing FOREIGN KEY constraint 'Employee_SecondTeam' on table 'Employees' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.\r\nCould not create constraint. See previous errors."} 

任何人可以幫助我嗎?

在此先感謝 權

回答

54

這在理論上是正確的,但因爲你的模型允許一個員工是第一和第二兩個團隊的成員,SQL服務器(未實體框架)不喜歡它。如果刪除Team,則會導致到同一個Employee實體的多個刪除路徑。

如果您將外鍵定義爲強制(不可爲空),則不能與級聯刪除一起使用,級聯刪除在EF代碼中默認使用。

如果你想避免異常,你必須使用流利的映射:

public Context : DbContext 
{ 
    public DbSet<Employee> Employees { get; set; } 
    public DbSet<Team> Teams { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Entity<Employee>() 
        .HasRequired(e => e.SecondTeam) 
        .WithMany(t => t.SecondEmployees) 
        .HasForeignKey(e => e.FirstTeamId) 
        .WillCascadeOnDelete(false); 

     ... 
    } 
} 

這將導致在場景中,你必須刪除在刪除前球隊手動SecondTeam的成員。

+0

但是,如果你讓EF生成密鑰它會使它們可以爲空(可選關係)。使用流利映射時,它也將使用列的名稱作爲外鍵。 – 2011-04-29 08:32:41

+0

謝謝拉迪斯拉夫。這正是我所期待的。 – Ray 2011-04-29 08:33:52

+0

抱歉刪除我的評論。但是,如果是這樣,我應該可以將外鍵屬性定義爲可以像public int那樣爲空嗎? FirstTeamId {get;設置;}? – Ray 2011-04-29 09:36:22

2

全部是在以前的答案是正確的,但有一點是錯誤的,而不是SecondTeamId

modelBuilder.Entity<Employee>() 
       .HasRequired(e => e.SecondTeam) 
       .WithMany(t => t.SecondEmployees) 
       .HasForeignKey(e => e.SecondTeamId) // mistake 
       .WillCascadeOnDelete(false); 

FirstTeamId將導致在SecondTeam navigation財產將永遠FirstTeam