如何在模型设计中指定ON DELETE NO ACTION外键约束?
目前,我有:
public class Status
{
[Required]
public int StatusId { get; set; }
[Required]
[DisplayName("Status")]
public string Name { get; set; }
}
public class Restuarant
{
public int RestaurantId { get; set; }
[Required]
public string Name { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
public string Telephone { get; set; }
[Required]
public int StatusId { get; set; }
public List<Menu> Menus { get; set; }
// NAVIGATION PROPERTIES
public virtual Status Status { get; set; }
}
public class Menu
{
public int MenuId { get; set; }
[Required]
public int RestaurantId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int StatusId { get; set; }
// NAVIGATION PROPERTIES
public virtual Status Status { get; set; }
public virtual Restaurant Restaurant { get; set; }
}
我的DbContext:
public class MenuEntities : DbContext
{
public DbSet<Status> Statuses { get; set; }
public DbSet<Restaurant> Restaurants { get; set; }
public DbSet<Menu> Menus { get; set; }
}
如你所见:
当然,如果状态被删除,我当然不希望级联,因为这会破坏一切。
更新
Mark Oreta在下面的例子中使用以下内容提到:
modelBuilder.Entity<FirstEntity>()
.HasMany(f => f.SecondEntities)
.WithOptional()
.WillCascadeOnDelete(false);
我在哪里放这个代码?在我的MenuEntities / DbContext类中? 任何人都可以提供一个使用它的例子吗?
更新 现在有点工作了,但是这在尝试播种数据库时产生了一个多重约束错误...
Multiplicity constraint violated. The role 'Menu_Status_Source' of the relationship 'LaCascadaWebApi.Models.Menu_Status' has multiplicity 1 or 0..1.
我的数据库初始化程序:
答案 0 :(得分:53)
您可以通过删除OnModelCreating方法中的级联删除约定来为整个上下文禁用它:
protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
或者,您可以使用流畅的映射(也在OnModelCreating中)为每个关系执行此操作:
编辑:您可以将其放入菜单实体
public class MenuEntities : DbContext
{
public DbSet<Status> Statuses { get; set; }
public DbSet<Restaurant> Restaurants { get; set; }
public DbSet<Menu> Menus { get; set; }
protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Entity<Menu>()
.HasRequired( f => f.Status )
.WithRequiredDependent()
.WillCascadeOnDelete( false );
modelBuilder.Entity<Restaurant>()
.HasRequired( f => f.Status )
.WithRequiredDependent()
.WillCascadeOnDelete( false );
}
}
答案 1 :(得分:8)
只需将FK属性设为可空,然后级联删除就会消失。
public int? StatusId { get; set; }
答案 2 :(得分:1)
对模型进行更改后,请确保通过添加-Force参数重新生成迁移文件。
添加迁移MigrationName -Force
答案 3 :(得分:0)
将它放入MenuEntities
班级(来自DbContext
的班级):
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
答案 4 :(得分:0)
要实现将其应用于所有实体,请将外键DeleteBehavior
修改为Restrict
。我们在OnModelCreating()
类的AppDbContext
方法中完成此操作
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
foreach (var foreignKey in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
{
foreignKey.DeleteBehavior = DeleteBehavior.Restrict;
}
}
构建解决方案。添加新的迁移并更新数据库。