Entity Framework 4.1 atrybut InverseProperty i ForeignKey

Two reference between Employee and Team entities with foreign keys. Więc zdefiniowałem dwa byty następująco

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

Myślałem, że teoretycznie jest poprawny, ale pokazuje wyjątek w następujący sposób:

{"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."}
Czy ktoś może mi pomóc? Z góry dzięki Kwon
Author: Dmitry Pavliv, 2011-04-29

2 answers

Jest to teoretycznie poprawne, ale SQL server (nie Entity framework) tego nie lubi, ponieważ twój model pozwala pojedynczemu pracownikowi być członkiem zarówno pierwszego, jak i drugiego zespołu. Jeśli Team zostanie usunięty, spowoduje to wiele ścieżek usuwania do tego samego elementu Employee.

To nie może być używane razem z Cascade delete, które są używane domyślnie w kodzie EF najpierw, jeśli zdefiniujesz klucz obcy jako obowiązkowy (Nie nullable).

Jeśli chcesz uniknąć wyjątku musisz użyć fluent "mapping": {]}

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);

        ...
    }
}

Spowoduje to, że będziesz musiał ręcznie usunąć członków SecondTeam przed usunięciem zespołu.

 54
Author: Ladislav Mrnka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-29 07:04:23

Wszystko jest poprawne w poprzedniej odpowiedzi, ale jedno jest złe

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

FirstTeamId zamiast SecondTeamId spowoduje, że w SecondTeam navigation właściwość będzie zawsze FirstTeam

 2
Author: Jiří Lebduška,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-29 10:08:16