Entity Framework 4.1 Атрибут InverseProperty и ForeignKey - PullRequest
31 голосов
/ 29 апреля 2011

Я создам две ссылки между сущностями 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 ]

54 голосов
/ 29 апреля 2011

Это теоретически правильно, но SQL-серверу (не Entity Framework) это не нравится, потому что ваша модель позволяет одному сотруднику быть членом первой и второй групп. Если 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 вручную перед удалением команды.

2 голосов
/ 29 апреля 2015

Все верно в предыдущем ответе, но одна вещь неправильна

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

FirstTeamId вместо SecondTeamId приведет к тому, что свойство SecondTeam navigation будет всегда FirstTeam

...