实体框架4.1 InverseProperty属性和ForeignKey

时间:2011-04-29 05:50:49

标签: c# mapping entity entity-framework-4.1 cascading-deletes

我将使用外键在Employee和Team实体之间创建两个引用。 所以我定义了两个实体如下

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."}

有人能帮助我吗?

提前致谢 权

2 个答案:

答案 0 :(得分: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的成员。

答案 1 :(得分:2)

以前的回答都是正确的,但有一点是错的

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

FirstTeamId代替SecondTeamId会导致SecondTeam navigation属性始终为FirstTeam

相关问题