2017-01-19 10 views
0

Я использую Entity Framework Сердечник с Code First подходом, но Получать следующие ошибки при обновлении базы данных:Entity Framework Core: Как решить Вводя ограничение внешнего ключа может вызвать циклы или несколько путей каскадных

Вводя FOREIGN KEY Ограничение «FK_AnEventUsers_Users_UserId» в таблице «AnEventUsers» может вызывать циклы или несколько каскадных путей. Укажите 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; } 
} 

вопрос я думал, что если удалить пользователя ссылка на AnEvent будет удален, а также ссылка на AnEventUser также будут удалены, так как является ссылкой на AnEventUser из AnEvent, а также мы получаем каскадные пути. Но я извлекаю удаления каскада от пользователя к AnEventUser с:

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

Но ошибка не разрешится, кто-нибудь увидеть, что это не так? Благодаря!

ответ

3

В вашем примере кода в 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 

} 

Второй вызов отменяется первым. Убери это.

+0

Я снял вторую часть, но она по-прежнему не работает. Во второй части говорится, что будет внешним ключом. В противном случае, как будет определено отношение для отношений «много-ко-многим» между AnEvent и User. Таким образом, удаление пользователя удалит AnEvent, у которого есть пользовательский ключ. У AnEventUser есть внешние ключи как для AnEvent, так и для User, здесь я думаю, что это проблема, которая приводит к каскадному удалению. Как правильно определить Fluent API? – Mu2tini

+0

Ваша первая часть с 'OnDelete (DeleteBehavior.Restrict);' правильно отменяет каскадное удаление в этой связи. Если вы хотите сконфигурировать что-то большее ('HasForreignKey') - поместите его здесь, не пишите же' HasOne (...) 'еще раз, он полностью отменяет первый. Еще раз проверьте и опубликуйте новый код (без дубликатов, но все еще создайте ошибку). – Dmitry

+0

Хммм. Вы обновляете миграцию с помощью «Remove-Migration» и «Add-Migration» после изменения до «Update-Database»? Обновление базы данных просто применяет уже существующие (старые) миграции. – Dmitry

0

Это то, что я от ответа Дмитрия,

и Он работал для меня.

Класс:

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

    public virtual Environment Environment { get; set; } 
} 

И это Mapping

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 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^