Я настроил то, что я считал довольно простой базой данных. Однако я получаю следующую ошибку.
Introducing FOREIGN KEY constraint 'FK_User_Suburb_SuburbId' on table 'User' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint or index. See previous errors.
Вот мой CATALOGCONtext:
using JobsLedger.CATALOG.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
namespace JobsLedger.CATALOG
{
public class CATALOGContext : DbContext
{
public DbSet<Tenant> Tenants { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<State> States { get; set; }
public DbSet<Suburb> Suburbs { get; set; }
public DbSet<CATALOGCounter> Counters { get; set; }
public CATALOGContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
entity.Relational().TableName = entity.DisplayName();
}
// User
modelBuilder.Entity<User>().Property(u => u.UserName).IsRequired().HasMaxLength(50);
modelBuilder.Entity<User>().Property(u => u.UserFirstName).IsRequired().HasMaxLength(100);
modelBuilder.Entity<User>().Property(u => u.UserLastName).IsRequired().HasMaxLength(100);
modelBuilder.Entity<User>().Property(u => u.Email).IsRequired().HasMaxLength(200);
modelBuilder.Entity<User>().Property(u => u.HashedPassword).IsRequired().HasMaxLength(200);
modelBuilder.Entity<User>().Property(u => u.Salt).IsRequired().HasMaxLength(200);
modelBuilder.Entity<User>()
.HasOne<Suburb>(s => s.Suburb)
.WithMany(u => u.Users)
.HasForeignKey(u => u.SuburbId)
.IsRequired(false);
// Role
modelBuilder.Entity<Role>().Property(r => r.Name).IsRequired().HasMaxLength(50);
modelBuilder.Entity<Role>()
.HasOne<User>(u => u.User)
.WithOne(r => r.Role)
.HasForeignKey<User>(u => u.RoleId);
// TenantAccount
modelBuilder.Entity<Tenant>().Property(t => t.TenantNo).HasMaxLength(20);
modelBuilder.Entity<Tenant>().Property(t => t.Company).HasMaxLength(100).IsRequired();
modelBuilder.Entity<Tenant>().Property(t => t.ContactLastName).HasDefaultValue(false).IsRequired();
modelBuilder.Entity<Tenant>().Property(t => t.Email).HasMaxLength(500).IsRequired();
modelBuilder.Entity<Tenant>().Property(t => t.MobilePhone).HasMaxLength(20).IsRequired();
modelBuilder.Entity<Tenant>().Property(t => t.OfficePhone).HasMaxLength(20);
modelBuilder.Entity<Tenant>().Property(t => t.CompanyEmail).HasMaxLength(500);
modelBuilder.Entity<Tenant>().Property(t => t.Address1).HasMaxLength(500);
modelBuilder.Entity<Tenant>().Property(t => t.Address2).HasMaxLength(500);
modelBuilder.Entity<Tenant>().Property(t => t.ABN).HasMaxLength(14);
modelBuilder.Entity<Tenant>().Property(t => t.Database).HasMaxLength(100).IsRequired();
modelBuilder.Entity<Tenant>().Property(t => t.IsLocked).HasDefaultValue(false);
modelBuilder.Entity<Tenant>()
.HasOne<User>(s => s.User)
.WithMany(ta => ta.Tenants)
.HasForeignKey(u => u.UserId);
modelBuilder.Entity<Tenant>()
.HasOne(s => s.Suburb)
.WithMany(ta => ta.Tenants)
.HasForeignKey(ta => ta.SuburbId);
// State
modelBuilder.Entity<State>().Property(s => s.StateShortName).HasMaxLength(3).IsRequired();
modelBuilder.Entity<State>().Property(s => s.StateName).HasMaxLength(30).IsRequired();
// Suburb
modelBuilder.Entity<Suburb>().Property(s => s.SuburbName).HasMaxLength(3).IsRequired();
modelBuilder.Entity<Suburb>().Property(s => s.PostCode).HasMaxLength(30).IsRequired();
modelBuilder.Entity<Suburb>()
.HasOne<State>(s => s.State)
.WithMany(su => su.Suburbs)
.HasForeignKey(st => st.StateId);
}
}
}
Вот мой пользователь:
...
public int? SuburbId { get; set; }
public Suburb Suburb { get; set; }
public int RoleId { get; set; }
public Role Role { get; set; }
public virtual ICollection<Tenant> Tenants { get; set; }
Вот мой пригород, о котором тоже упоминалось..
Интересно, может ли кто-нибудь указать, почему миграция работает, но когда я пытаюсь развернуть базу данных, она выдает ошибку с вышеуказанной ошибкой.
Саймон





Ошибка уже говорит, что вам нужно сделать. Укажите, что он должен делать, когда есть действие. Вы должны добавить метод .OnDelete() к каждому определению внешнего ключа.
modelBuilder.Entity<Tenant>()
.HasOne<User>(s => s.User)
.WithMany(ta => ta.Tenants)
.HasForeignKey(u => u.UserId)
.OnDelete(DeleteBehavior.Restrict);
Для получения дополнительной информации, пожалуйста, прочитайте https://www.learnentityframeworkcore.com/configuration/fluent-api/ondelete-method
Конфигурация вашего User объекта ForeignFeyСвободный API должна быть следующей:
modelBuilder.Entity<User>()
.HasOne<Suburb>(s => s.Suburb)
.WithMany(u => u.Users)
.HasForeignKey(u => u.SuburbId)
.IsRequired(false);
.OnDelete(DeleteBehavior.Restrict); // <-- Here it is
Для других, которые находят этот вопрос, этого достаточно:
modelBuilder.Entity<User>()
.HasOne(u => u.Suburb)
.WithMany(s => s.Users)
.OnDelete(DeleteBehavior.Restrict);
Если вам не нужно свойство списка в Suburb с Users, вы также можете сделать это так:
modelBuilder.Entity<User>()
.HasOne(u => u.Suburb)
.WithMany()
.OnDelete(DeleteBehavior.Restrict);
Я прикрепляю этот ответ к своему списку ответов