C# EF核心中多对多关系的级联引用完整性约束
我正在使用EFCore3.1.5和Asp.NETCore3.1。当我尝试添加迁移时,出现下一个错误: Microsoft.Data.SqlClient.SqlException(0x80131904):在表“PhotoDevice”上引入外键约束“FK_PhotoDevice_Device_DeviceId”可能会导致循环或多个级联路径。指定“在删除时不执行操作”或“在更新时不执行操作”,或修改其他外键约束 我有下一个实体和配置:C# EF核心中多对多关系的级联引用完整性约束,c#,entity-framework,asp.net-core,entity-framework-core,many-to-many,C#,Entity Framework,Asp.net Core,Entity Framework Core,Many To Many,我正在使用EFCore3.1.5和Asp.NETCore3.1。当我尝试添加迁移时,出现下一个错误: Microsoft.Data.SqlClient.SqlException(0x80131904):在表“PhotoDevice”上引入外键约束“FK_PhotoDevice_Device_DeviceId”可能会导致循环或多个级联路径。指定“在删除时不执行操作”或“在更新时不执行操作”,或修改其他外键约束 我有下一个实体和配置: public class User { [Key]
public class User {
[Key]
public long Id { get; set; }
// Fields
public IEnumerable<Device> Devices { get; set; }
public IEnumerable<Photo> Photos { get; set; }
}
public class Photo {
[Key]
public long Id { get; set; }
// Fields
[ForeignKey("User")]
public long UserRef { get; set; }
public User User { get; set; }
public IEnumerable<PhotoDevice> PhotoDevices { get; set; }
}
public class Device {
[Key]
public long Id { get; set; }
// Fields
[ForeignKey("User")]
public long UserRef { get; set; }
public User User { get; set; }
public IEnumerable<PhotoDevice> PhotoDevices { get; set; }
}
public class PhotoDevice {
{
public long? PhotoRef { get; set; }
public Photo Photo { get; set; }
public long? DeviceRef { get; set; }
public Device Device { get; set; }
}
public class AppDbContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Photo> Photos { get; set; }
public DbSet<Device> Devices { get; set; }
public DbSet<PhotoDevice> PhotoDevices { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
{
Database.Migrate();
}
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Photo>()
.HasOne(photo => photo.User)
.WithMany(user => user.Photos);
builder.Entity<Device>()
.HasOne(device => device.User)
.WithMany(user => user.Devices);
builder.Entity<PhotoDevice>()
.HasKey(bc => new { bc.PhotoRef, bc.DeviceRef });
builder.Entity<PhotoDevice>()
.HasOne(bc => bc.Photo)
.WithMany(b => b.PhotoDevices)
.HasForeignKey(bc => bc.PhotoRef);
builder.Entity<PhotoDevice>()
.HasOne(bc => bc.Device)
.WithMany(c => c.PhotoDevices)
.HasForeignKey(bc => bc.DeviceRef);
}
}
公共类用户{
[关键]
公共长Id{get;set;}
//田地
公共IEnumerable设备{get;set;}
公共IEnumerable照片{get;set;}
}
公开课照片{
[关键]
公共长Id{get;set;}
//田地
[外键(“用户”)]
公共长UserRef{get;set;}
公共用户{get;set;}
公共IEnumerable光电设备{get;set;}
}
公共类设备{
[关键]
公共长Id{get;set;}
//田地
[外键(“用户”)]
公共长UserRef{get;set;}
公共用户{get;set;}
公共IEnumerable光电设备{get;set;}
}
公共级光电器件{
{
公共long?PhotoRef{get;set;}
公共照片照片{get;set;}
公共长设备{get;set;}
公用设备设备{get;set;}
}
公共类AppDbContext:DbContext
{
公共数据库集用户{get;set;}
公共数据库集照片{get;set;}
公共数据库集设备{get;set;}
公共DbSet光电设备{get;set;}
公共AppDbContext(DbContextOptions选项)
:基本(选项)
{
Database.Migrate();
}
模型创建时受保护的覆盖无效(ModelBuilder)
{
builder.Entity()
.HasOne(photo=>photo.User)
.WithMany(user=>user.Photos);
builder.Entity()
.HasOne(设备=>device.User)
.WithMany(用户=>user.Devices);
builder.Entity()
.HasKey(bc=>new{bc.PhotoRef,bc.DeviceRef});
builder.Entity()
.HasOne(bc=>bc.Photo)
.有许多(b=>b.光电器件)
.HasForeignKey(bc=>bc.PhotoRef);
builder.Entity()
.HasOne(bc=>bc.Device)
.有许多(c=>c.光电器件)
.HasForeignKey(bc=>bc.DeviceRef);
}
}
我发现问题与级联连接的唯一性无关。但现在我感到困惑。因为我认为这种结构是必要的,我不想删除任何FK。如果我需要下一个逻辑,我如何解决问题:
- 当用户删除时,与用户相关的所有设备和照片也将被删除
- 当设备或照片被删除时,与被删除实体相关的所有PhotoDevice记录也被删除
OnDelete(DeleteBehavior)
明确指定您需要哪种级联行为即可
例如,以下情况将导致成功创建模型,但对于实际应用程序,您需要自行决定在何处以及如何打破级联:
builder.Entity()
.HasOne(bc=>bc.Photo)
.有许多(b=>b.光电器件)
.HasForeignKey(bc=>bc.PhotoRef)
.OnDelete(DeleteBehavior.Restrict);//lauxjpn所说的是正确的,但是请注意,当您添加时.OnDelete(DeleteBehavior.Restrict);
在此之后,请记住删除所有以前的迁移,否则它仍将报告错误。谢谢!您的回答非常完整,帮助我解决了问题