實體框架核心:如何解決引入FOREIGN KEY約束可能會導致循環或多個級​​聯路徑

entity-framework entity-framework-core foreign-keys

我正在使用Entity Framework Core和Code First方法,但在更新數據庫時收到以下錯誤:

在表'AnEventUsers'上引入FOREIGN KEY約束'FK_AnEventUsers_Users_UserId'可能會導致循環或多個級​​聯路徑。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY約束。無法創建約束或索引。查看以前的錯誤。

我的實體是這些:

public class AnEvent
{
    public int AnEventId { get; set; }
    public DateTime Time { get; set; }
    public Gender Gender { get; set; }
    public int Duration { get; set; }
    public Category Category { get; set; }
    public int MinParticipants { get; set; }
    public int MaxParticipants { get; set; }
    public string Description { get; set; }
    public Status EventStatus { get; set; }
    public int MinAge { get; set; }
    public int MaxAge { get; set; }
    public double Longitude { get; set; }
    public double Latitude { get; set; }

    public ICollection<AnEventUser> AnEventUsers { get; set; }

    public int UserId { get; set; }
    public User User { get; set; }
}


public class User
{
    public int UserId { get; set; }
    public int Age { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Gender Gender { get; set; }
    public double Rating { get; set; }

    public ICollection<AnEventUser> AnEventUsers { get; set; }
}

public class AnEventUser
{
    public int AnEventId { get; set; }
    public AnEvent AnEvent { get; set; }

    public int UserId { get; set; }
    public User User { get; set; }

}

public class ApplicationDbContext:DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options):base(options)
    { }


    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<AnEventUser>()
            .HasOne(u => u.User).WithMany(u => u.AnEventUsers).IsRequired().OnDelete(DeleteBehavior.Restrict);


        modelBuilder.Entity<AnEventUser>()
            .HasKey(t => new { t.AnEventId, t.UserId });

        modelBuilder.Entity<AnEventUser>()
            .HasOne(pt => pt.AnEvent)
            .WithMany(p => p.AnEventUsers)
            .HasForeignKey(pt => pt.AnEventId);

        modelBuilder.Entity<AnEventUser>()
            .HasOne(eu => eu.User)
            .WithMany(e => e.AnEventUsers)
            .HasForeignKey(eu => eu.UserId);

    }

    public DbSet<AnEvent> Events { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<AnEventUser> AnEventUsers { get; set; }
}

我認為的問題是,如果我們刪除User,將刪除對AnEvent的引用,並且還將刪除對AnEventUser的引用,因為AnEvent引用了AnEventUser,我們也獲得了級聯路徑。但我刪除了從User到AnEventUser的刪除級聯:

 modelBuilder.Entity<AnEventUser>()
        .HasOne(u => u.User).WithMany(u => u.AnEventUsers).IsRequired().OnDelete(DeleteBehavior.Restrict);

但是錯誤沒有得到解決,有人看到了什麼問題嗎?謝謝!

一般承認的答案

OnModelCreating的示例代碼中,您已聲明了modelBuilder.Entity<AnEventUser>().HasOne(e => e.User)...兩次:在方法開始時和結束時。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<AnEventUser>()       // THIS IS FIRST
        .HasOne(u => u.User).WithMany(u => u.AnEventUsers).IsRequired().OnDelete(DeleteBehavior.Restrict);


    modelBuilder.Entity<AnEventUser>()
        .HasKey(t => new { t.AnEventId, t.UserId });

    modelBuilder.Entity<AnEventUser>()
        .HasOne(pt => pt.AnEvent)
        .WithMany(p => p.AnEventUsers)
        .HasForeignKey(pt => pt.AnEventId);

    modelBuilder.Entity<AnEventUser>()       // THIS IS SECOND.
        .HasOne(eu => eu.User)               // THIS LINES
        .WithMany(e => e.AnEventUsers)       //   SHOULD BE
        .HasForeignKey(eu => eu.UserId);     //   REMOVED

}

第二次調用首先覆蓋。去掉它。


熱門答案

這就是我從德米特里的回答中所做的,

它對我有用。

類:

public class EnviornmentControls
{
    public int Id { get; set; }
    ...

    public virtual Environment Environment { get; set; }
}

這是映射

public EnviornmentControlsMap(EntityTypeBuilder<EnviornmentControls> entity)
{
        entity.HasKey(m => m.Id);           

        entity.HasOne(m => m.Environment)
            .WithMany(m => m.EnviornmentControls)
            .HasForeignKey(m => m.EnvironmentID)
            .OnDelete(DeleteBehavior.Restrict); // added OnDelete to avoid sercular reference 
}


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因